row & derivatives context menu

This commit is contained in:
shamsmosowi
2022-03-06 22:09:07 +08:00
parent e66b8dd842
commit c57b973214
6 changed files with 100 additions and 39 deletions

View File

@@ -165,7 +165,6 @@ export default function useMonacoCustomizations({
rendererOptions: { "just-types": "true" },
});
const newLib = result.lines.join("\n").replaceAll("export ", "");
// console.log(newLib);
monaco?.languages.typescript.javascriptDefaults.addExtraLib(newLib);
}
};
@@ -191,7 +190,6 @@ export default function useMonacoCustomizations({
// Set row definitions
useEffect(() => {
if (!monaco || !rowyRun || !tableState?.columns) return;
console.log("setting row definitions");
try {
const rowDefinition =
Object.keys(tableState.columns)

View File

@@ -1,4 +1,4 @@
import { Menu } from "@mui/material";
import { Divider, Menu } from "@mui/material";
import { default as MenuItem } from "./MenuItem";
import { IContextMenuItem } from "./MenuItem";
@@ -6,14 +6,14 @@ interface IMenuContents {
anchorEl: HTMLElement;
open: boolean;
handleClose: () => void;
items: IContextMenuItem[];
groups: IContextMenuItem[][];
}
export function MenuContents({
anchorEl,
open,
handleClose,
items,
groups,
}: IMenuContents) {
const handleContext = (e: React.MouseEvent) => e.preventDefault();
@@ -41,8 +41,13 @@ export function MenuContents({
}}
onContextMenu={handleContext}
>
{items.map((item, indx: number) => (
<MenuItem key={indx} {...item} />
{groups.map((items, groupIndex) => (
<>
{groupIndex > 0 && <Divider />}
{items.map((item, index: number) => (
<MenuItem key={`contextMenu-${groupIndex}-${index}`} {...item} />
))}
</>
))}
</Menu>
);

View File

@@ -3,26 +3,88 @@ import { getColumnType, getFieldProp } from "@src/components/fields";
import { useProjectContext } from "@src/contexts/ProjectContext";
import { MenuContents } from "./MenuContent";
import { useContextMenuAtom } from "@src/atoms/ContextMenu";
import { FieldType } from "@src/constants/fields";
import DuplicateIcon from "@src/assets/icons/Copy";
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
import { useAppContext } from "@src/contexts/AppContext";
import { IContextMenuItem } from "./MenuItem";
import { useConfirmation } from "@src/components/ConfirmationDialog/Context";
export default function ContextMenu() {
const { tableState } = useProjectContext();
const { requestConfirmation } = useConfirmation();
const { tableState, deleteRow, addRow } = useProjectContext();
const { userRoles } = useAppContext();
const { anchorEle, selectedCell, resetContextMenu } = useContextMenuAtom();
const columns = tableState?.columns;
const selectedColIndex = selectedCell?.colIndex;
const selectedColumn = _find(columns, { index: selectedColIndex });
if (!selectedColumn) return <></>;
const configActions =
getFieldProp("contextMenuActions", selectedColumn.type) ||
function empty() {};
const actions = configActions(selectedCell, resetContextMenu) || [];
const menuActions = getFieldProp("contextMenuActions", selectedColumn.type);
if (!anchorEle || actions.length === 0) return <></>;
const actionGroups: IContextMenuItem[][] = [];
const actions = menuActions
? menuActions(selectedCell, resetContextMenu)
: [];
if (actions.length > 0) actionGroups.push(actions);
let hasRenderedFieldActions = false;
if (selectedColumn.type === FieldType.derivative) {
const renderedFieldMenuActions = getFieldProp(
"contextMenuActions",
selectedColumn.config.renderFieldType
);
if (renderedFieldMenuActions) {
actionGroups.push(
renderedFieldMenuActions(selectedCell, resetContextMenu)
);
hasRenderedFieldActions = true;
}
}
if (!anchorEle || (actions.length === 0 && !hasRenderedFieldActions))
return <></>;
const row = tableState?.rows[selectedCell!.rowIndex];
if (userRoles.includes("ADMIN") && row) {
const rowActions = [
{
label: "Duplicate Row",
icon: <DuplicateIcon />,
onClick: () => {
const { ref, ...clonedRow } = row;
addRow!(clonedRow, undefined, { type: "smaller" });
},
},
{
label: "Delete Row",
variant: "secondary",
icon: <DeleteIcon color="warning" />,
onClick: () => {
requestConfirmation({
title: "Delete row?",
customBody: (
<>
Row path:
<br />
<code style={{ userSelect: "all", wordBreak: "break-all" }}>
{row.ref.path}
</code>
</>
),
confirm: "Delete",
confirmColor: "error",
handleConfirm: () => deleteRow?.(row.id),
});
resetContextMenu();
},
},
];
actionGroups.push(rowActions);
}
return (
<MenuContents
anchorEl={anchorEle}
open={Boolean(anchorEle)}
handleClose={resetContextMenu}
items={actions}
groups={actionGroups}
/>
);
}

View File

@@ -45,14 +45,8 @@ export default function FinalColumn({ row }: FormatterProps<any, any>) {
color="inherit"
disabled={!addRow}
onClick={() => {
const clonedRow = { ...row };
// remove metadata
delete clonedRow.ref;
delete clonedRow.rowHeight;
Object.keys(clonedRow).forEach((key) => {
if (clonedRow[key] === undefined) delete clonedRow[key];
});
if (addRow) addRow!(clonedRow, undefined, { type: "smaller" });
const { ref, ...clonedRow } = row;
addRow!(clonedRow, undefined, { type: "smaller" });
}}
aria-label="Duplicate row"
className="row-hover-iconButton"

View File

@@ -1,15 +1,11 @@
import _find from "lodash/find";
import _get from "lodash/get";
import Cut from "@mui/icons-material/ContentCut";
import CopyCells from "@src/assets/icons/CopyCells";
import Paste from "@mui/icons-material/ContentPaste";
import EvalIcon from "@mui/icons-material/Replay";
import ReEvalIcon from "@mui/icons-material/Replay";
import EvalIcon from "@mui/icons-material/PlayCircle";
import { useProjectContext } from "@src/contexts/ProjectContext";
import { useSnackbar } from "notistack";
import { SelectedCell } from "@src/atoms/ContextMenu";
import { getFieldProp, getColumnType } from "@src/components/fields";
import { runRoutes } from "@src/constants/runRoutes";
export interface IContextMenuActions {
@@ -22,7 +18,7 @@ export default function ContextMenuActions(
selectedCell: SelectedCell,
reset: () => void | Promise<void>
): IContextMenuActions[] {
const { tableState, deleteCell, updateCell, rowyRun } = useProjectContext();
const { tableState, rowyRun } = useProjectContext();
const { enqueueSnackbar } = useSnackbar();
const columns = tableState?.columns;
const rows = tableState?.rows;
@@ -30,18 +26,18 @@ export default function ContextMenuActions(
const selectedColIndex = selectedCell?.colIndex;
const selectedCol = _find(columns, { index: selectedColIndex });
if (!selectedCol) return [];
// don't show evalute button if function has external dependency
const code =
selectedCol.config.derivativeFn ?? selectedCol.config.script ?? "";
if (code.includes("require(")) return [];
const selectedRow = rows?.[selectedRowIndex];
const cellValue = _get(selectedRow, selectedCol.key);
console.log({
selectedCol,
schemaDocPath: tableState?.config.tableConfig.path,
});
const handleClose = async () => await reset?.();
const handleEvaluate = async () => {
try {
if (!selectedCol || !rowyRun || !selectedRow) return;
rowyRun({
const result = await rowyRun({
route: runRoutes.evaluateDerivative,
body: {
ref: {
@@ -51,13 +47,22 @@ export default function ContextMenuActions(
columnKey: selectedCol.key,
},
});
if (result.success === false) {
enqueueSnackbar(result.message, { variant: "error" });
}
} catch (error) {
enqueueSnackbar(`Failed: ${error}`, { variant: "error" });
}
handleClose();
};
const isEmpty =
cellValue === "" || cellValue === null || cellValue === undefined;
const contextMenuActions = [
{ label: "evalute", icon: <EvalIcon />, onClick: handleEvaluate },
{
label: isEmpty ? "Evaluate" : "Re-evaluate",
icon: isEmpty ? <EvalIcon /> : <ReEvalIcon />,
onClick: handleEvaluate,
},
];
return contextMenuActions;

View File

@@ -35,8 +35,6 @@ const rowsReducer = (prevRows: any, update: any) => {
switch (update.type) {
case "onSnapshot":
const snapshotDocs = update.docs;
console.log("onSnapshot", snapshotDocs);
// Get rows that may not be part of the snapshot
// Rows with missing required fields havent been written to the db yet
// Out of order rows will appear on top
@@ -168,7 +166,6 @@ const useTableData = () => {
const unsubscribe = query.limit(limit).onSnapshot(
(snapshot) => {
console.log("snapshot", snapshot);
// if (snapshot.docs.length > 0) {
rowsDispatch({
type: "onSnapshot",