mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-28 16:06:41 +01:00
feat(formula-field): fix function regexp, expand listener fields
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
|
||||
@@ -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<T>(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);
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user