diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx index b99c11295..03285ac47 100644 --- a/src/components/Table/Table.tsx +++ b/src/components/Table/Table.tsx @@ -31,7 +31,10 @@ import { tablePageAtom, updateColumnAtom, selectedCellAtom, + tableSortsAtom, + tableIdAtom, } from "@src/atoms/tableScope"; +import { projectScope, userSettingsAtom } from "@src/atoms/projectScope"; import { getFieldType, getFieldProp } from "@src/components/fields"; import { useKeyboardNavigation } from "./useKeyboardNavigation"; import { useMenuAction } from "./useMenuAction"; @@ -98,6 +101,11 @@ export default function Table({ const updateColumn = useSetAtom(updateColumnAtom, tableScope); + // Get user settings and tableId for applying sort sorting + const [userSettings] = useAtom(userSettingsAtom, projectScope); + const [tableId] = useAtom(tableIdAtom, tableScope); + const setTableSorts = useSetAtom(tableSortsAtom, tableScope); + // Store a **state** and reference to the container element // so the state can re-render `TableBody`, preventing virtualization // not detecting scroll if the container element was initially `null` @@ -233,6 +241,18 @@ export default function Table({ containerRef, ]); + // apply user default sort on first render + const [applySort, setApplySort] = useState(true); + useEffect(() => { + if (applySort && Object.keys(tableSchema).length) { + const userDefaultSort = userSettings.tables?.[tableId]?.sorts || []; + setTableSorts( + userDefaultSort.length ? userDefaultSort : tableSchema.sorts || [] + ); + setApplySort(false); + } + }, [tableSchema, userSettings, tableId, setTableSorts, applySort]); + return (
setContainerEl(el)} diff --git a/src/components/fields/Formula/DisplayCell.tsx b/src/components/fields/Formula/DisplayCell.tsx index 24c7e2c66..adf59b9df 100644 --- a/src/components/fields/Formula/DisplayCell.tsx +++ b/src/components/fields/Formula/DisplayCell.tsx @@ -7,6 +7,7 @@ import { defaultFn, getDisplayCell } from "./util"; export default function Formula(props: IDisplayCellProps) { const { result, error, loading } = useFormula({ row: props.row, + ref: props._rowy_ref, listenerFields: props.column.config?.listenerFields || [], formulaFn: props.column.config?.formulaFn || defaultFn, }); diff --git a/src/components/fields/Formula/Settings.tsx b/src/components/fields/Formula/Settings.tsx index 912ad6b51..666615fe7 100644 --- a/src/components/fields/Formula/Settings.tsx +++ b/src/components/fields/Formula/Settings.tsx @@ -3,14 +3,7 @@ import { useDebouncedCallback } from "use-debounce"; import { useAtom } from "jotai"; import MultiSelect from "@rowy/multiselect"; -import { - Grid, - InputLabel, - Typography, - Stack, - FormHelperText, - Tooltip, -} from "@mui/material"; +import { Grid, InputLabel, Stack, FormHelperText } from "@mui/material"; import { tableColumnsOrderedAtom, @@ -142,7 +135,11 @@ export default function Settings({ additionalVariables={[ { key: "row", - description: `Current row's data`, + description: `row has the value of doc.data() it has type definitions using this table's schema, but you can only access formula's listener fields.`, + }, + { + key: "ref", + description: `reference object that holds the readonly reference of the row document.(i.e ref.id)`, }, ]} /> diff --git a/src/components/fields/Formula/TableSourcePreview.ts b/src/components/fields/Formula/TableSourcePreview.ts index 81d72662e..c4536c01e 100644 --- a/src/components/fields/Formula/TableSourcePreview.ts +++ b/src/components/fields/Formula/TableSourcePreview.ts @@ -1,7 +1,7 @@ import { useCallback, useEffect } from "react"; import { useSetAtom } from "jotai"; import { useAtomCallback } from "jotai/utils"; -import { cloneDeep, findIndex, initial, sortBy } from "lodash-es"; +import { cloneDeep, findIndex, sortBy } from "lodash-es"; import { _deleteRowDbAtom, diff --git a/src/components/fields/Formula/formula.d.ts b/src/components/fields/Formula/formula.d.ts index 517b7e570..69fcde0d8 100644 --- a/src/components/fields/Formula/formula.d.ts +++ b/src/components/fields/Formula/formula.d.ts @@ -1,6 +1,8 @@ +type RowRef = Pick; + type FormulaContext = { row: Row; - // ref: FirebaseFirestore.DocumentReference; + ref: RowRef; // storage: firebasestorage.Storage; // db: FirebaseFirestore.Firestore; }; diff --git a/src/components/fields/Formula/useFormula.tsx b/src/components/fields/Formula/useFormula.tsx index b4cacccaa..64d0fa6a7 100644 --- a/src/components/fields/Formula/useFormula.tsx +++ b/src/components/fields/Formula/useFormula.tsx @@ -2,17 +2,19 @@ import { useEffect, useMemo, useState } from "react"; import { pick, zipObject } from "lodash-es"; import { useAtom } from "jotai"; -import { TableRow } from "@src/types/table"; +import { TableRow, TableRowRef } from "@src/types/table"; import { tableColumnsOrderedAtom, tableScope } from "@src/atoms/tableScope"; import { listenerFieldTypes, useDeepCompareMemoize } from "./util"; export const useFormula = ({ row, + ref, listenerFields, formulaFn, }: { row: TableRow; + ref: TableRowRef; listenerFields: string[]; formulaFn: string; }) => { @@ -61,6 +63,7 @@ export const useFormula = ({ worker.postMessage({ formulaFn, row: JSON.stringify(availableFields), + ref: { id: ref.id, path: ref.path }, }); return () => { diff --git a/src/components/fields/Formula/worker.ts b/src/components/fields/Formula/worker.ts index 4baf08234..a0d85fd36 100644 --- a/src/components/fields/Formula/worker.ts +++ b/src/components/fields/Formula/worker.ts @@ -1,14 +1,15 @@ onmessage = async ({ data }) => { try { - const { formulaFn, row } = data; + const { formulaFn, row, ref } = data; const AsyncFunction = async function () {}.constructor as any; const [_, fnBody] = formulaFn.match(/=>\s*({?[\s\S]*}?)$/); if (!fnBody) return; const fn = new AsyncFunction( "row", + "ref", `const fn = async () => \n${fnBody}\n return fn();` ); - const result = await fn(JSON.parse(row)); + const result = await fn(JSON.parse(row), ref); postMessage({ result }); } catch (error: any) { console.error("Error: ", error); diff --git a/src/sources/TableSourceFirestore/TableSourceFirestore.tsx b/src/sources/TableSourceFirestore/TableSourceFirestore.tsx index 67833d533..9f3e2cedf 100644 --- a/src/sources/TableSourceFirestore/TableSourceFirestore.tsx +++ b/src/sources/TableSourceFirestore/TableSourceFirestore.tsx @@ -39,7 +39,6 @@ import { getTableSchemaPath } from "@src/utils/table"; import { TableSchema } from "@src/types/table"; import { firebaseDbAtom } from "@src/sources/ProjectSourceFirebase"; import { projectScope } from "@src/atoms/projectScope"; -import useApplySorts from "./useApplySorts"; /** * When rendered, provides atom values for top-level tables and sub-tables @@ -142,7 +141,6 @@ export const TableSourceFirestore = memo(function TableSourceFirestore() { } ); - useApplySorts(); useAuditChange(); useBulkWriteDb(); diff --git a/src/sources/TableSourceFirestore/useApplySorts.ts b/src/sources/TableSourceFirestore/useApplySorts.ts deleted file mode 100644 index 5edf6b0a3..000000000 --- a/src/sources/TableSourceFirestore/useApplySorts.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { useEffect, useState } from "react"; -import { useAtom, useSetAtom } from "jotai"; - -import { projectScope, userSettingsAtom } from "@src/atoms/projectScope"; -import { - tableIdAtom, - tableSchemaAtom, - tableScope, - tableSortsAtom, -} from "@src/atoms/tableScope"; - -/** - * Sets the value of tableSortsAtom - */ -export default function useApplySorts() { - // Apply the sorts - - const setTableSorts = useSetAtom(tableSortsAtom, tableScope); - const [userSettings] = useAtom(userSettingsAtom, projectScope); - const [tableId] = useAtom(tableIdAtom, tableScope); - const [tableSchema] = useAtom(tableSchemaAtom, tableScope); - - // Apply only once - const [applySort, setApplySort] = useState(true); - - useEffect(() => { - if (applySort && Object.keys(tableSchema).length) { - const userDefaultSort = userSettings.tables?.[tableId]?.sorts || []; - setTableSorts( - userDefaultSort.length ? userDefaultSort : tableSchema.sorts || [] - ); - setApplySort(false); - } - }, [setTableSorts, userSettings, tableId, applySort, tableSchema]); -}