All files / src/pages/flowsheet-page/flowsheet/PropertiesSidebar/PropertyPanel ControlTarget.tsx

100% Statements 19/19
100% Branches 14/14
100% Functions 10/10
100% Lines 19/19

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                                  1802x               529x       1077x 529x   548x       3400x 1796x   1604x         559x       1636x                 5733x   5733x 16x             5733x 5733x                                               2411x   2411x 1x               2411x                                
import { Replace } from "lucide-react";
import {
  PropertyInfoRead,
  PropertyValueRead,
  useCoreControlvaluesCreateMutation,
} from "../../../../../api/apiStore.gen";
import { PropertySelector } from "./PropertySelector";
 
type ControlTargetProps = {
  property: PropertyInfoRead;
  value: PropertyValueRead;
  disabled: boolean;
  children: React.ReactNode;
};
 
function isStateVariable(value: PropertyValueRead) {
  // Is a state var/parameter that is default accessible.
  return (
    value.enabled /*|| (!value.recycleConnection && p.recycleConnection)*/ &&
    !value.controlManipulated &&
    !value.controlSetPoint
  );
}
function isFreeVariable(value: PropertyValueRead) {
  // Is a propertyValue that is calculated
  return !value.enabled && !value.controlManipulated && !value.controlSetPoint;
}
 
function _hasFreeVariable(valueDict) {
  if (valueDict.id !== undefined) {
    return isFreeVariable(valueDict);
  } else {
    return Object.values(valueDict).some(_hasFreeVariable);
  }
}
function _hasStateVariable(valueDict) {
  if (valueDict.id !== undefined) {
    return isStateVariable(valueDict);
  } else {
    return Object.values(valueDict).some(_hasStateVariable);
  }
}
 
function hasFreeVariable(property: PropertyInfoRead) {
  return property.type === "numeric" && _hasFreeVariable(property.values);
}
 
function hasStateVariable(property: PropertyInfoRead) {
  return property.type === "numeric" && _hasStateVariable(property.values);
}
 
export function ControlTarget({
  value,
  property,
  children,
}: ControlTargetProps) {
  // We can memoise filtering for the graphic object to save some computation
  const [createControlvalue] = useCoreControlvaluesCreateMutation();
 
  const onSelect = async (manipulatedProperty: PropertyValueRead) => {
    createControlvalue({
      controlValue: {
        manipulated: manipulatedProperty.id,
        setPoint: value.id,
      },
    });
  };
  const title = `Choose a parameter for ${property.displayName} to replace`;
  return (
    <PropertySelector
      onSelect={onSelect}
      title={title}
      variant="secondary" // buttons Shaded as these are variables that are currently set
      // Filter to only properties that are state variables and not controlled in any way.
      filter={hasStateVariable}
      filterValue={isStateVariable}
      header=""
      description=""
    >
      {children}
    </PropertySelector>
  );
}
 
export function CalculateFromTarget({
  value,
  property,
}: {
  value: PropertyValueRead;
  property: PropertyInfoRead;
}) {
  // This is the same thing, but in reverse. we are choosing the property to target from the property that will be calculated
  const [createControlvalue] = useCoreControlvaluesCreateMutation();
 
  const onSelect = async (setpointProperty: PropertyValueRead) => {
    createControlvalue({
      controlValue: {
        manipulated: value.id,
        setPoint: setpointProperty.id,
      },
    });
  };
 
  return (
    <PropertySelector
      className="w-full font-normal mt-2"
      onSelect={onSelect}
      variant="outline" // buttons not shaded as these are parameters right now
      title={`Choose a variable to replace ${property.displayName}.`}
      // Filter to only properties that are not state variables or controlled
      filter={hasFreeVariable}
      filterValue={isFreeVariable}
      header=""
      description=""
    >
      <Replace aria-label={"replace" + property.key} />
    </PropertySelector>
  );
}