FarmBot/Farmbot-Web-App

View on GitHub
frontend/tools/custom_tool_graphics.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import React from "react";
import { t } from "../i18next_wrapper";
import { BlurableInput, Color } from "../ui";
import { DevSettings } from "../settings/dev/dev_support";
import { reduceFarmwareEnv } from "../farmware/state_to_props";
import { store } from "../redux/store";
import { UserEnv } from "../devices/interfaces";
import { SaveFarmwareEnv } from "../farmware/interfaces";
import {
  reduceToolName, ToolName,
} from "../farm_designer/map/tool_graphics/all_tools";

interface CustomToolGraphics {
  top?: string;
  front?: string;
  side?: string;
  mirror?: string;
}

export interface CustomToolGraphicsInputProps {
  toolName: string;
  dispatch: Function;
  saveFarmwareEnv: SaveFarmwareEnv;
  env: UserEnv;
}

export interface CustomToolProfileProps {
  toolName: string | undefined;
  xToolMiddle: number;
  yToolBottom: number;
  sideView: boolean;
}

export interface CustomToolTopProps {
  toolName: string | undefined;
  x: number;
  y: number;
}

const INPUTS = (): Record<keyof CustomToolGraphics, string> => ({
  top: "",
  front: "",
  side: t("same as front"),
  mirror: t("not mirrored"),
});

export const getCustomToolGraphicsKey = (toolName: string) =>
  `custom_tool_graphics_${toolName.toLowerCase()}`;

const getCustomToolGraphics = (
  toolName: string | undefined,
  env?: UserEnv,
): CustomToolGraphics | undefined => {
  if (!toolName) { return undefined; }
  const toolGraphicsKey = getCustomToolGraphicsKey(toolName);
  const envs = env || reduceFarmwareEnv(store.getState().resources.index);
  const customToolGraphics = JSON.parse(envs[toolGraphicsKey] || "{}");
  return customToolGraphics;
};

export const CustomToolGraphicsInput =
  (props: CustomToolGraphicsInputProps) => {
    const { toolName, dispatch } = props;
    const customToolGraphics = getCustomToolGraphics(toolName, props.env) || {};
    const saveGraphics = (graphics: CustomToolGraphics) => props.saveFarmwareEnv(
      getCustomToolGraphicsKey(toolName), JSON.stringify(graphics));
    const customTool = reduceToolName(toolName) == ToolName.tool;
    return (DevSettings.futureFeaturesEnabled() && customTool && toolName)
      ? <details className={"custom-tool-graphics-input"}>
        <summary><label>{t("custom tool graphics")}</label></summary>
        <p>path = M0,0 ______</p>
        {Object.entries(INPUTS())
          .map(([view, placeholder]: [keyof CustomToolGraphics, string]) =>
            <div className={"graphics-input"} key={view}>
              <label>{t(view)}</label>
              <BlurableInput
                value={customToolGraphics[view] || ""}
                placeholder={placeholder}
                allowEmpty={true}
                onCommit={e => {
                  customToolGraphics[view] = e.currentTarget.value;
                  dispatch(saveGraphics(customToolGraphics));
                }} />
            </div>)}
      </details>
      : <div />;
  };

export const CustomToolProfile = (props: CustomToolProfileProps) => {
  const { toolName, sideView, xToolMiddle, yToolBottom } = props;
  const customToolGraphics = getCustomToolGraphics(toolName);
  if (!customToolGraphics?.front) { return <g id={"custom"} />; }
  const customProfilePath = (sideView && customToolGraphics.side)
    ? customToolGraphics.side
    : customToolGraphics.front;
  const origin = `${xToolMiddle} ${yToolBottom}`;
  const transformOrigin = `${xToolMiddle}px ${yToolBottom}px`;
  return <g id={"custom-implement-profile"}
    fill={Color.darkGray} opacity={0.25}>
    <path d={`M${origin} ${customProfilePath}`} />
    {customToolGraphics.mirror &&
      <path style={{ transform: "scale(-1,1)", transformOrigin }}
        d={`M${origin} ${customProfilePath}`} />}
  </g>;
};

export const CustomToolTop = (props: CustomToolTopProps) => {
  const customToolGraphics = getCustomToolGraphics(props.toolName);
  if (!customToolGraphics?.top) { return <g id={"custom"} />; }
  return <path id={"custom-top"}
    d={`M${props.x} ${props.y} ${customToolGraphics.top}`}
    fill={Color.darkGray} opacity={0.25} />;
};