All files / src/commands AddUnitOp.tsx

89.28% Statements 25/28
85.71% Branches 6/7
50% Functions 2/4
91.66% Lines 22/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117                                76x                 67062x 67062x 67062x 67062x 67062x   67062x         67062x     72x   72x         72x   72x                   72x           72x                 72x             67062x                                     7930x   81x 81x 7930x   4698x           8011x          
import { useReactFlow } from "@xyflow/react";
import { defineCommand } from "just-search-it";
import objs from "@/data/objects.json";
import {
  ObjectTypeEnum,
  useUnitopsSimulationobjectsCreateMutation,
} from "../api/apiStore.gen";
import { useCurrentGroupId } from "../hooks/flowsheetObjects";
import { useProjectId } from "../hooks/project";
import { useSearchParam } from "../hooks/searchParams";
import { useUndoRedoStore } from "../hooks/useUndoRedoStore";
import { isStreamType } from "../lib/isStream";
import { createModel } from "../pages/flowsheet-page/flowsheet/Canvas/FlowsheetFunctions";
import { createAddCommand } from "../utils/commandCreators";
import { RegisterCommand } from "./CommandProvider";
 
const AddUnitOp = defineCommand<[ObjectTypeEnum], void>("addUnitOp");
 
const AddUnitOpCommand = ({
  unitOpType,
  canvasDiv,
}: {
  unitOpType: ObjectTypeEnum;
  canvasDiv: React.MutableRefObject<null>;
}) => {
  const [currentGroupId] = useSearchParam("CurrentGroupID");
  const rootGroup = useCurrentGroupId();
  const flowsheetId = useProjectId();
  const { addHistory } = useUndoRedoStore();
  const { screenToFlowPosition } = useReactFlow();
 
  const image = new URL(
    "/assets/UpdatedIcons/" + unitOpType + ".svg",
    import.meta.url,
  ).href;
 
  const [createObject] = useUnitopsSimulationobjectsCreateMutation();
 
  const action = async () => {
    const pane = canvasDiv.current?.getBoundingClientRect();
 
    const screenPoint = {
      x: pane.left + pane.width / 2,
      y: pane.top + pane.height / 2,
    };
 
    const createPosition = screenToFlowPosition(screenPoint);
 
    const model = createModel(
      createPosition.x,
      createPosition.y,
      unitOpType,
      flowsheetId,
      currentGroupId || rootGroup,
    );
 
    try {
      // Create the object first
      const response = await createObject({
        simulationObject: model,
      }).unwrap();
 
      // CRITICAL FIX: Track the ADD operation for undo/redo
      if (response?.id) {
        const addCommand = createAddCommand({
          objectId: response.id,
          graphicObjectId: response.graphics_object?.id || response.id,
          objectType: unitOpType,
          simulationObject: response,
          position: createPosition,
          groupId: currentGroupId ? parseInt(currentGroupId) : rootGroup,
        });
 
        addHistory(addCommand);
      }
    } catch (error) {
      console.error("[AddUnitOp] Failed to create unit operation:", error);
    }
  };
 
  return (
    <RegisterCommand
      command={AddUnitOp}
      args={[unitOpType]}
      name={"Add " + objs[unitOpType].displayType}
      description={
        "Add a " + objs[unitOpType].displayType + " to the flowsheet"
      }
      group="Add Object"
      icon={
        <div className="bg-white p-1 rounded-md">
          <img src={image} alt={unitOpType} className="icon-ls" />
        </div>
      }
      action={action}
    />
  );
};
 
const UnitOpCommands = ({ canvasDiv }) => {
  return (
    <>
      {Object.keys(objs)
        .filter((key) => !isStreamType(key as ObjectTypeEnum))
        .map((key) => (
          <AddUnitOpCommand
            key={key}
            unitOpType={key as ObjectTypeEnum}
            canvasDiv={canvasDiv}
          />
        ))}
    </>
  );
};
 
export { AddUnitOp, AddUnitOpCommand, UnitOpCommands };