All files / src/pages/flowsheet-page/flowsheet/Canvas FlowsheetCommands.tsx

87.03% Statements 47/54
58.53% Branches 24/41
50% Functions 2/4
92.68% Lines 38/41

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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132                          103x       103x 103x       12808x             2528x   2528x 2528x 2528x 2528x   2528x 7x         7x           4358x   2528x 7x       2778x     2528x 6815x     6815x                       1560x 125x   2653x   2528x     2528x           125x       2653x     2653x 3278x 790x   2528x       2528x   3318x 1479x   6815x                   7x       7x         6965x 7208x      
import { useReactFlow } from "@xyflow/react";
import { defineCommand } from "just-search-it";
import { ArrowUpDown, Hand, MousePointer } from "lucide-react";
import { useSelector } from "react-redux";
import { useSearchParams } from "react-router-dom";
import { ObjectTypeEnum } from "@/api/apiStore.gen";
import { RegisterCommand } from "@/commands/CommandProvider";
import { useGraphicsObjects } from "@/hooks/flowsheetObjects";
import { setClick } from "@/store/ClickSlice";
import { useAppDispatch } from "@/store/hooks";
import { RootState } from "@/store/store";
import { ContentTypes } from "../LeftSideBar/LeftSideBarTabDefinitions";
 
export const TogglePointerState = defineCommand<
  [state: "select" | "hand"],
  void
>("togglePointerState");
export const GoToObject = defineCommand<[id: number], void>("goToObject");
export const AutoSortCanvas = defineCommand<[], Promise<void> | void>(
  "autoSortCanvas",
);
 
export function FlowsheetCommands({
  togglePointerState,
  handleAutoSortCanvas,
}: {
  togglePointerState: () => void;
  handleAutoSortCanvas: () => Promise<void> | void;
}) {
  const pointerState = useSelector((state: RootState) => state.pointer);
  //get all objects
  const graphicsObjects = useGraphicsObjects();
  const { getViewport, setCenter } = useReactFlow();
  const [, setParams] = useSearchParams("object");
  const dispatch = useAppDispatch();
  //Change selected object
  function selectObject(objectId: number, parentGroup: string) {
    setParams({
      parentGroup: parentGroup.toString(),
      object: objectId.toString(),
      content: ContentTypes.objectDetails,
    });
    dispatch(
      setClick({
        type: "unit",
        id: objectId,
      }),
    );
  }
 
  function centerObject(x: number, y: number, width: number, height: number) {
    void setCenter(x + width / 2, y + height / 2, {
      zoom: getViewport().zoom,
      duration: 500,
    });
  }
 
  //Manage existing flowsheet icon objects
  const displayObjectIcon = (objectType: ObjectTypeEnum) => {
    const image = new URL(
      "/assets/UpdatedIcons/" + objectType + ".svg",
      import.meta.url,
    ).href;
 
    return (
      <div className="bg-white p-1 rounded-md">
        <img src={image} alt={objectType} className="icon-ls" />
      </div>
    );
  };
 
  // TODO: registerCommand for e.g zoom to fit doesn't need to be here.
  // We could just put a useRegisterCommand hook in the file the zoomToFit function is in
  return (
    <>
      <RegisterCommand
        command={TogglePointerState}
        args={[pointerState.state === "select" ? "hand" : "select"]}
        name={
          pointerState.state === "select" ? "Move Pointer" : "Select Pointer"
        }
        description={
          pointerState.state === "select"
            ? "Allows you to move around the design without accidentally selecting objects."
            : "Allows you to move and select elements in the flowsheet."
        }
        group="Display & flowsheet controls"
        icon={
          pointerState.state === "select" ? (
            <Hand className="icon-ls" />
          ) : (
            <MousePointer className="icon-ls" />
          )
        }
        action={togglePointerState}
        shortcuts={[{ key: pointerState.state === "select" ? "M" : "S" }]}
      />
      <RegisterCommand
        command={AutoSortCanvas}
        args={[]}
        name="Auto-sort Canvas"
        description="Deterministically arrange the current group from left to right based on process connectivity."
        group="Display & flowsheet controls"
        icon={<ArrowUpDown className="icon-ls" />}
        action={handleAutoSortCanvas}
      />
      {graphicsObjects?.map((unitOp) => {
        return (
          unitOp.group && (
            <RegisterCommand
              key={unitOp.simulationObject.componentName}
              command={GoToObject}
              args={[unitOp.id]}
              name={`Go To ${unitOp.simulationObject.componentName}`}
              description={`Unit Op: ${unitOp.simulationObject.componentName}`}
              icon={displayObjectIcon(unitOp.simulationObject.objectType)}
              group="Go to object"
              action={() => {
                selectObject(
                  unitOp.simulationObject.id,
                  unitOp.group?.toString(),
                );
                centerObject(unitOp.x, unitOp.y, unitOp.width, unitOp.height);
              }}
            />
          )
        );
      })}
    </>
  );
}