Merge pull request #1056 from rowyio/ROWY-831-preview-table

ROWY-831: Add preview table
This commit is contained in:
Shams
2023-02-15 17:37:33 +01:00
committed by GitHub
5 changed files with 220 additions and 4 deletions

View File

@@ -0,0 +1,82 @@
import { Provider, useAtom } from "jotai";
import { currentUserAtom } from "@src/atoms/projectScope";
import {
tableRowsDbAtom,
tableScope,
tableSettingsAtom,
} from "@src/atoms/tableScope";
import TablePage from "@src/pages/Table/TablePage";
import { TableSchema } from "@src/types/table";
import { Box, InputLabel } from "@mui/material";
import TableSourcePreview from "./TableSourcePreview";
const PreviewTable = ({ tableSchema }: { tableSchema: TableSchema }) => {
const [currentUser] = useAtom(currentUserAtom, tableScope);
const [tableSettings] = useAtom(tableSettingsAtom, tableScope);
return (
<Box>
<InputLabel>Preview table</InputLabel>
<Provider
key={"preview-table"}
scope={tableScope}
initialValues={[
[currentUserAtom, currentUser],
[
tableSettingsAtom,
{
...tableSettings,
id: "preview-table",
collection: "preview-collection",
},
],
[tableRowsDbAtom, []],
]}
>
<TableSourcePreview tableSchema={tableSchema} />
<Box
sx={{
maxHeight: 300,
overflow: "auto",
marginTop: 1,
marginLeft: 0,
// table toolbar
"& > div:first-child": {
display: "none",
},
// table grid
"& > div:nth-of-type(2)": {
height: "unset",
},
// emtpy state
"& .empty-state": {
display: "none",
},
// column actions - add column
'& [data-col-id="_rowy_column_actions"]': {
display: "none",
},
// row headers - sort by, column settings
'& [data-row-id="_rowy_header"] > button': {
display: "none",
},
// row headers - drag handler
'& [data-row-id="_rowy_header"] > .column-drag-handle': {
display: "none !important",
},
// row headers - resize handler
'& [data-row-id="_rowy_header"] >:last-child': {
display: "none !important",
},
}}
>
<TablePage disableModals={true} disableSideDrawer={true} />
</Box>
</Provider>
</Box>
);
};
export default PreviewTable;

View File

@@ -1,4 +1,4 @@
import { lazy, Suspense } from "react";
import { lazy, Suspense, useMemo } from "react";
import { useDebouncedCallback } from "use-debounce";
import { useAtom } from "jotai";
import MultiSelect from "@rowy/multiselect";
@@ -12,12 +12,20 @@ import {
Tooltip,
} from "@mui/material";
import {
tableColumnsOrderedAtom,
tableSchemaAtom,
tableScope,
} from "@src/atoms/tableScope";
import FieldSkeleton from "@src/components/SideDrawer/FieldSkeleton";
import { ISettingsProps } from "@src/components/fields/types";
import { tableColumnsOrderedAtom, tableScope } from "@src/atoms/tableScope";
import FieldsDropdown from "@src/components/ColumnModals/FieldsDropdown";
import { DEFAULT_COL_WIDTH, DEFAULT_ROW_HEIGHT } from "@src/components/Table";
import { ColumnConfig } from "@src/types/table";
import { defaultFn, listenerFieldTypes, outputFieldTypes } from "./util";
import PreviewTable from "./PreviewTable";
import { getFieldProp } from "..";
/* eslint-disable import/no-webpack-loader-syntax */
@@ -38,14 +46,41 @@ const diagnosticsOptions = {
export default function Settings({
config,
fieldName,
onChange,
onBlur,
errors,
}: ISettingsProps) {
const [tableSchema] = useAtom(tableSchemaAtom, tableScope);
const [tableColumnsOrdered] = useAtom(tableColumnsOrderedAtom, tableScope);
const returnType = getFieldProp("dataType", config.renderFieldType) ?? "any";
const formulaFn = config?.formulaFn ? config.formulaFn : defaultFn;
const previewTableSchema = useMemo(() => {
const columns = tableSchema.columns || {};
return {
...tableSchema,
columns: Object.keys(columns).reduce((previewSchema, key) => {
if ((config.listenerFields || []).includes(columns[key].fieldName)) {
previewSchema[key] = {
...columns[key],
fixed: false,
width: DEFAULT_COL_WIDTH,
};
}
if (columns[key].fieldName === fieldName) {
previewSchema[key] = {
...columns[key],
config,
fixed: true,
};
}
return previewSchema;
}, {} as { [key: string]: ColumnConfig }),
rowHeight: DEFAULT_ROW_HEIGHT,
};
}, [config, fieldName, tableSchema]);
return (
<Stack spacing={1}>
<Grid container direction="row" spacing={2} flexWrap="nowrap">
@@ -125,6 +160,7 @@ export default function Settings({
/>
</Suspense>
</div>
<PreviewTable tableSchema={previewTableSchema} />
</Stack>
);
}

View File

@@ -0,0 +1,98 @@
import { useCallback, useEffect } from "react";
import { useSetAtom } from "jotai";
import { useAtomCallback } from "jotai/utils";
import { cloneDeep, findIndex, initial, sortBy } from "lodash-es";
import {
_deleteRowDbAtom,
_updateRowDbAtom,
tableNextPageAtom,
tableRowsDbAtom,
tableSchemaAtom,
tableScope,
} from "@src/atoms/tableScope";
import { TableRow, TableSchema } from "@src/types/table";
import { updateRowData } from "@src/utils/table";
const initialRows = [
{
_rowy_ref: {
id: "zzzzzzzzzzzzzzzzzzzw",
path: "preview-collection/zzzzzzzzzzzzzzzzzzzw",
},
},
{
_rowy_ref: {
id: "zzzzzzzzzzzzzzzzzzzx",
path: "preview-collection/zzzzzzzzzzzzzzzzzzzx",
},
},
{
_rowy_ref: {
id: "zzzzzzzzzzzzzzzzzzzy",
path: "preview-collection/zzzzzzzzzzzzzzzzzzzy",
},
},
];
const TableSourcePreview = ({ tableSchema }: { tableSchema: TableSchema }) => {
const setTableSchemaAtom = useSetAtom(tableSchemaAtom, tableScope);
const setRows = useSetAtom(tableRowsDbAtom, tableScope);
useEffect(() => {
setRows(initialRows);
}, [setRows]);
useEffect(() => {
setTableSchemaAtom(() => ({
...tableSchema,
_rowy_ref: "preview",
}));
}, [tableSchema, setTableSchemaAtom]);
const readRowsDb = useAtomCallback(
useCallback((get) => get(tableRowsDbAtom) || initialRows, []),
tableScope
);
const setUpdateRowDb = useSetAtom(_updateRowDbAtom, tableScope);
setUpdateRowDb(() => async (path: string, update: Partial<TableRow>) => {
const rows = await readRowsDb();
const index = findIndex(rows, ["_rowy_ref.path", path]);
if (index === -1) {
setRows(
sortBy(
[
...rows,
{ ...update, _rowy_ref: { id: path.split("/").pop()!, path } },
],
["_rowy_ref.id"]
)
);
} else {
const updatedRows = [...rows];
updatedRows[index] = cloneDeep(rows[index]);
updatedRows[index] = updateRowData(updatedRows[index], update);
setRows(updatedRows);
}
return Promise.resolve();
});
const setDeleteRowDb = useSetAtom(_deleteRowDbAtom, tableScope);
setDeleteRowDb(() => async (path: string) => {
const rows = await readRowsDb();
const index = findIndex(rows, ["_rowy_ref.path", path]);
if (index > -1) {
setRows(rows.filter((_, idx) => idx !== index));
}
return Promise.resolve();
});
const setNextPageAtom = useSetAtom(tableNextPageAtom, tableScope);
setNextPageAtom({ loading: false, available: false });
return null;
};
export default TableSourcePreview;

View File

@@ -60,7 +60,7 @@ export const useFormula = ({
worker.postMessage({
formulaFn,
row: availableFields,
row: JSON.stringify(availableFields),
});
return () => {

View File

@@ -8,7 +8,7 @@ onmessage = async ({ data }) => {
"row",
`const fn = async () => \n${fnBody}\n return fn();`
);
const result = await fn(row);
const result = await fn(JSON.parse(row));
postMessage({ result });
} catch (error: any) {
console.error("Error: ", error);