import React from "react"; import { Checkbox, Select } from "@dndbeyond/character-components/es"; import { Constants, FormatUtils, HtmlSelectOption, AccessUtils, } from "@dndbeyond/character-rules-engine/es"; import { CollapsibleContent } from "~/components/CollapsibleContent"; import { Link } from "~/components/Link"; export interface AffectedFeatureInfo { name: string; definitionKey: string; disabled: boolean; } interface OptionalFeatureProps { name: string; requiredLevel?: number; description: string | null; featureType: Constants.FeatureTypeEnum | null; definitionKey: string; affectedFeatureDefinitionKey: string | null; isSelected: boolean; onSelection: ( definitionKey: string, affectedFeatureDefinitionKey: string | null ) => void; onRemoveSelectionPromise?: ( definitionKey: string, newIsEnabled: boolean, accept: () => void, reject: () => void ) => void; onChangeReplacementPromise?: ( definitionKey: string, newAffectedDefinitionKey: string | null, oldAffectedDefinitionKey: string | null, accept: () => void, reject: () => void ) => void; affectedFeatures: Array; accessType: Constants.AccessTypeEnum; } export class OptionalFeature extends React.PureComponent< OptionalFeatureProps, {} > { handleSelection = (isEnabled: boolean): void => { const { featureType, onSelection, definitionKey, affectedFeatures } = this.props; switch (featureType) { case Constants.FeatureTypeEnum.REPLACEMENT: { if (isEnabled) { const affectedFeatureDefinitionKey: string | null = affectedFeatures.length === 1 ? affectedFeatures[0].definitionKey : null; onSelection(definitionKey, affectedFeatureDefinitionKey); } break; } case Constants.FeatureTypeEnum.ADDITIONAL: { if (isEnabled) { onSelection(definitionKey, null); } break; } default: //not implemented } }; transformDefinitionKey = (definitionKey: string): string | null => { return definitionKey.length ? definitionKey : null; }; handleReplacementChangePromise = ( newAffectedDefinitionKey: string, oldAffectedDefinitionKey: string, accept: () => void, reject: () => void ) => { const { onChangeReplacementPromise, definitionKey } = this.props; if (onChangeReplacementPromise) { onChangeReplacementPromise( definitionKey, this.transformDefinitionKey(newAffectedDefinitionKey), this.transformDefinitionKey(oldAffectedDefinitionKey), accept, reject ); } }; handleUnselectPromise = ( newIsEnabled: boolean, accept: () => void, reject: () => void ) => { const { onRemoveSelectionPromise, definitionKey } = this.props; if (onRemoveSelectionPromise) { onRemoveSelectionPromise(definitionKey, newIsEnabled, accept, reject); } }; renderReplacements = (): React.ReactNode => { const { affectedFeatures, isSelected, featureType, affectedFeatureDefinitionKey, } = this.props; if (!affectedFeatures.length) { return null; } const introText: Array = ["Replaces:"]; const disabledText: string = "(already replaced)"; if (affectedFeatures.length === 1) { introText.push(affectedFeatures[0].name); if (affectedFeatures[0].disabled) { introText.push(disabledText); } } const options: Array = []; if (affectedFeatures.length > 1) { affectedFeatures.forEach((feature) => { const label: Array = [feature.name]; if (feature.disabled) { label.push(disabledText); } options.push({ label: label.join(" "), value: feature.definitionKey, disabled: feature.disabled, }); }); } const classNames: Array = ["ct-optional-feature__select"]; if ( featureType === Constants.FeatureTypeEnum.REPLACEMENT && isSelected && affectedFeatureDefinitionKey === null ) { classNames.push("ct-optional-feature__select--todo"); } return (
{introText.join(" ")}
{options.length > 1 && (