lara-typescript/src/page-item-authoring/managed-interactives/customize.tsx
import * as React from "react";
import { useState } from "react";
import { IManagedInteractive } from "./index";
import { ILibraryInteractive } from "../common/hooks/use-library-interactives";
import { ReadOnlyFormField } from "../common/components/read-only-form-field";
import { AspectRatioChooser,
AspectRatioMode,
IAspectRatioChooserValues,
availableAspectRatios
} from "../common/components/aspect-ratio-chooser";
import { CustomizableOption } from "../common/components/customizable-option";
import { Checkbox } from "../common/components/checkbox";
interface Props {
managedInteractive: IManagedInteractive;
libraryInteractive: ILibraryInteractive;
defaultClickToPlayPrompt: string;
}
export const CustomizeManagedInteractive: React.FC<Props> = (props) => {
const { managedInteractive, libraryInteractive, defaultClickToPlayPrompt } = props;
const {
inherit_aspect_ratio_method,
custom_aspect_ratio_method,
custom_native_width,
custom_native_height,
inherit_click_to_play,
custom_click_to_play,
custom_click_to_play_prompt,
inherit_full_window,
custom_full_window,
inherit_image_url,
custom_image_url,
show_in_featured_question_report,
linked_interactive_item_id
} = managedInteractive;
const [inheritAspectRatio, setInheritAspectRatio] = useState(inherit_aspect_ratio_method);
const [customAspectRatioValues, setCustomAspectRatioValues] = useState<IAspectRatioChooserValues>({
width: custom_native_width,
height: custom_native_height,
mode: (custom_aspect_ratio_method || "DEFAULT") as AspectRatioMode
});
const [inheritClickToPlay, setInheritClickToPlay] = useState(inherit_click_to_play);
const [customClickToPlay, setCustomClickToPlay] = useState(custom_click_to_play);
const [customClickToPlayPrompt, setCustomClickToPlayPrompt] = useState(custom_click_to_play_prompt);
const [inheritFullWindow, setInheritFullWindow] = useState(inherit_full_window);
const [inheritImageUrl, setInheritImageUrl] = useState(inherit_image_url);
const [customImageUrl, setCustomImageUrl] = useState(custom_image_url);
const handleBooleanOption = (setter: (value: boolean) => void) => {
return (e: React.ChangeEvent<HTMLInputElement>) => {
const value = !!(e.target.checked && (e.target.value === "true"));
setter(value);
};
};
const handleStringOption = (setter: (value: string) => void) => {
return (e: React.ChangeEvent<HTMLInputElement>) => {
setter(e.target.value);
};
};
const handleAspectRatioChange = (values: IAspectRatioChooserValues) => setCustomAspectRatioValues(values);
const handleChangeCustomizeAspectRatio = handleBooleanOption(setInheritAspectRatio);
const handleChangeClickToPlay = handleBooleanOption(setInheritClickToPlay);
const handleChangeCustomClickToPlay = handleBooleanOption(setCustomClickToPlay);
const handleChangeCustomClickToPlayPrompt = handleStringOption(setCustomClickToPlayPrompt);
const handleChangeCustomImageUrl = handleStringOption(setCustomImageUrl);
const clickToPlayEnabled = (inheritClickToPlay && libraryInteractive.click_to_play) ||
(!inheritClickToPlay && customClickToPlay);
const renderCommonFields = () => {
return <>
{libraryInteractive.enable_learner_state ?
<>
<fieldset>
<legend>Link Saved Work From</legend>
<input
type="text"
name="linked_interactive_item_id"
defaultValue={`${linked_interactive_item_id || ""}`}
/>
<div className="warning">
<em>Warning</em>: Please do not link to another interactive
unless the interactive knows how to load prior work.
</div>
</fieldset>
<fieldset>
<legend>Featured Report</legend>
<Checkbox
id="show_in_featured_question_report"
name="show_in_featured_question_report"
defaultChecked={show_in_featured_question_report}
label="Show in featured question report?"
/>
</fieldset>
</>
: undefined}
</>;
};
if (!libraryInteractive.customizable) {
const renderAspectRatioValues = () => {
const mode = (inherit_aspect_ratio_method
? libraryInteractive.aspect_ratio_method
: custom_aspect_ratio_method) as AspectRatioMode;
if (mode !== "MANUAL") {
return undefined;
}
const values = {
width: inherit_aspect_ratio_method ? libraryInteractive.native_width : custom_native_width,
height: inherit_aspect_ratio_method ? libraryInteractive.native_height : custom_native_height,
};
return <span style={{marginLeft: 10}}>(width: {values.width}, height: {values.height})</span>;
};
return (
<div>
{renderCommonFields()}
<p>
The selected library interactive ({libraryInteractive.name})
does not support customizing the additional advanced options.
Here are their values:
</p>
<ReadOnlyFormField
legend="Aspect Ratio"
value={availableAspectRatios[custom_aspect_ratio_method as AspectRatioMode]}
inherit={true}
inherited={inherit_aspect_ratio_method}
inheritedValue={availableAspectRatios[libraryInteractive.aspect_ratio_method as AspectRatioMode]}
>
{renderAspectRatioValues()}
</ReadOnlyFormField>
</div>
);
}
const renderClickToPlayOptions = () => {
const defaultPrompt = libraryInteractive.click_to_play_prompt || defaultClickToPlayPrompt;
return <>
<div className="customizable-option-setting">
<strong>Default Prompt Text</strong>
<span className="default-click-to-play-prompt">{defaultPrompt}</span>
</div>
<div className="customizable-option-setting">
<label htmlFor="custom-click-to-play-prompt">
<strong>
Custom Prompt Text
</strong>
</label>
<input
type="text"
id="custom-click-to-play-prompt"
name="custom_click_to_play_prompt"
value={customClickToPlayPrompt}
onChange={handleChangeCustomClickToPlayPrompt}
/>
</div>
<CustomizableOption
label="Full Window"
inheritName="inherit_full_window"
customName="custom_full_window"
inherit={inheritFullWindow}
defaultLabel={libraryInteractive.full_window ? "Enabled" : "Disabled"}
onChange={setInheritFullWindow}
>
<Checkbox
name="custom_full_window"
defaultChecked={custom_full_window}
label="Enabled"
/>
</CustomizableOption>
<CustomizableOption
label="Image URL"
inheritName="inherit_image_url"
customName="custom_image_url"
inherit={inheritImageUrl}
defaultLabel={libraryInteractive.image_url ? libraryInteractive.image_url : "No default image URL"}
onChange={setInheritImageUrl}
>
<div className="customizable-option-setting">
<label htmlFor="custom_image_url">Custom Image URL</label>
<input
type="text"
id="custom_image_url"
name="custom_image_url"
value={customImageUrl}
onChange={handleChangeCustomImageUrl}
/>
</div>
</CustomizableOption>
</>;
};
// this generates a form element that renders inside the rails popup form
return <>
{renderCommonFields()}
<fieldset>
<legend>Aspect Ratio</legend>
<input
type="hidden"
name="custom_aspect_ratio_method"
value={customAspectRatioValues.mode}
/>
<input
type="hidden"
name="inherit_native_width"
value={inheritAspectRatio ? "true" : "false"}
/>
<input
type="hidden"
name="custom_native_width"
value={customAspectRatioValues.width}
/>
<input
type="hidden"
name="inherit_native_height"
value={inheritAspectRatio ? "true" : "false"}
/>
<input
type="hidden"
name="custom_native_height"
value={customAspectRatioValues.height}
/>
<input
type="radio"
id="inherit-aspect-ratio-method"
name="inherit_aspect_ratio_method"
value="true"
defaultChecked={inheritAspectRatio}
onChange={handleChangeCustomizeAspectRatio}
/>
<label htmlFor="inherit-aspect-ratio-method" className="radioLabel">
Use default:
<strong>
{availableAspectRatios[libraryInteractive.aspect_ratio_method as AspectRatioMode]}
{libraryInteractive.aspect_ratio_method === "MANUAL"
? ` (width: ${libraryInteractive.native_width}, height: ${libraryInteractive.native_height})`
: undefined}
</strong>
</label>
<div className="customizable-option">
<input
type="radio"
id="inherit-aspect-ratio-method"
name="inherit_aspect_ratio_method"
value="false"
defaultChecked={!inheritAspectRatio}
onChange={handleChangeCustomizeAspectRatio}
/>
<label htmlFor="inherit-aspect-ratio-method" className="radioLabel">
Customize
{!inheritAspectRatio &&
<AspectRatioChooser
width={customAspectRatioValues.width}
height={customAspectRatioValues.height}
mode={customAspectRatioValues.mode}
onChange={handleAspectRatioChange}
/>
}
</label>
</div>
</fieldset>
<fieldset>
<legend>Click to Play</legend>
<div className="option_group">
<div className="customizable-option">
<input
type="radio"
id="inherit-click-to-play"
name="inherit_click_to_play"
value="true"
defaultChecked={inheritClickToPlay}
onChange={handleChangeClickToPlay}
/>
<label htmlFor="inherit-click-to-play" className="radioLabel">
Use default: <strong>{libraryInteractive.click_to_play ? "Enabled" : "Disabled"}</strong>
</label>
</div>
<div className="customizable-option">
<input
type="radio"
id="inherit-click-to-play"
name="inherit_click_to_play"
value="false"
defaultChecked={!inheritClickToPlay}
onChange={handleChangeClickToPlay}
/>
<label htmlFor="inherit-click-to-play" className="radioLabel">
Customize
</label>
{!inheritClickToPlay &&
<div className="customizable-option-setting">
<input
id="custom-click-to-play"
type="checkbox"
name="custom_click_to_play"
value="true"
defaultChecked={customClickToPlay}
onChange={handleChangeCustomClickToPlay}
/>
<label htmlFor="custom-click-to-play">
Enabled
</label>
</div>
}
{clickToPlayEnabled && renderClickToPlayOptions()}
</div>
</div>
</fieldset>
</>;
};