import React, {
ChangeEvent,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react";
import { AttachCreatedFile, IDisplayComponentRef } from "./DisplayComponent";
import { Components, PropNames } from "./Components";
import {
ComponentTitle,
Container,
GridItem,
Label,
TextInput,
WideGridItem,
WideTextInput,
WideTextArea,
} from "./EditComponents";
import Repository from "../../common/repository/repository";
import config from "../../config.json";
import { ColorSelector } from "./ColorSelector";
import {
AssetType,
IAsset,
IDirection,
IObjectFit,
ITemperatureType,
IAnimatedDrmDotPosition,
AssetNames,
} from "../../digital_assets_management/interfaces/IAsset";
import { useTranslations } from "../../i18n/useTranslations";
import { Input } from "reactstrap";
import { ThumbnailModal } from "../../common/components/ThumbnailModal";
import * as Constants from "../constants/component-constants";
import * as Global_Constants from "../../common/constants/shared-constants";
import * as Property_Constants from "../../common/constants/property-constants";
interface IComponentProps {
component: IDisplayComponentRef | null;
configuration: any;
onValueChanged: (x: number, y: number, width: number, height: number) => void;
onDeleteComponent?: (c: string) => void;
onDuplicateComponent?: (c: IDisplayComponentRef) => void;
}
export const ComponentPropertyBar = ({
component,
configuration,
onValueChanged,
onDeleteComponent,
onDuplicateComponent,
}: IComponentProps) => {
const [checked, setChecked] = useState(true);
const [isPlaying, setIsPlaying] = useState(false);
const [align, setAlign] = useState("");
const [extraProps, setExtraProps] = useState(
{} as { [key: string]: any | number | boolean }
);
const refX = useRef<any>();
const refY = useRef<any>();
const refW = useRef<any>();
const refH = useRef<any>();
const i18n = useTranslations();
const [createdFile, setCreatedFile] = useState({
name: "",
fileptr: Global_Constants.NOT_A_FP,
} as AttachCreatedFile);
const [styleAssets, setStyleAssets] = useState<IAsset[]>([]);
const [arrowImage, setArrowImage] = useState<string | undefined>(undefined);
const [imageAssets, setImageAssets] = useState<IAsset[]>([]);
const [videoAssets, setVideoAssets] = useState<IAsset[]>([]);
const [multiTextChecked, setMultiTextChecked] = useState(false);
const [direction, setDirection] = useState<string>("left");
const directionOptional = useRef([
IDirection.LEFT,
IDirection.RIGHT,
IDirection.UP,
IDirection.DOWN,
]);
const [fitObject, setFitObject] = useState<string>();
const objectsFitOptions = useRef([
IObjectFit.CONTAIN,
IObjectFit.COVER,
IObjectFit.fill,
]);
const [, setTempartureType] = useState();
const tempartureTypesOptions = useRef([
ITemperatureType.CELSIUS,
ITemperatureType.FAHRENHEIT,
]);
const [temperatureUnit, setTemperatureUnit] = useState<string>();
const [ddrInputEvents, setDDRInputEvents] = useState<string>();
const [animatedDrmDotOptionValue, setAnimatedDrmDotOptionValue] =
useState("default");
const animatedDrmDotPosition = useRef([
IAnimatedDrmDotPosition.DEFAULT,
IAnimatedDrmDotPosition.UPPER,
IAnimatedDrmDotPosition.LOWER,
IAnimatedDrmDotPosition.ZIGZAG,
]);
const [showImageModal, setShowImageModal] = useState(false);
const openImageModal = () => {
setShowImageModal(true);
};
const closeImageModal = () => {
setShowImageModal(false);
};
const [searchQuery, setSearchQuery] = useState("");
const [numStations, setNumStations] = useState(2); // Default number of stations
const [numberofArrows, setArrowIndex] = useState(0);
const [fontOptions, setFontOptions] = useState([]);
const [selectedFont, setSelectedFont] = useState("");
const dataChanged = () => {
const bounds = component!.getBounds();
let x = parseInt(refX.current!.value);
x = isNaN(x) ? bounds.x : x;
let y = parseInt(refY.current!.value);
y = isNaN(y) ? bounds.y : y;
let width = parseInt(refW.current!.value);
width = isNaN(width) ? bounds.width : width;
let height = parseInt(refH.current!.value);
height = isNaN(height) ? bounds.height : height;
onValueChanged(x, y, width, height);
};
useEffect(() => {
if (extraProps.direction) {
setDirection(extraProps.direction.toString());
} else {
setDirection("left");
}
}, [extraProps.direction]);
useEffect(() => {
setExtraProps({});
if (!component) return;
const bounds = component.getBounds();
setValue(refX.current!, Math.round(bounds.x));
setValue(refY.current!, Math.round(bounds.y));
setValue(refW.current!, Math.round(bounds.width));
setValue(refH.current!, Math.round(bounds.height));
const props = component.getExtraProps();
if (props) {
setExtraProps(props);
setChecked(props[Property_Constants.IS_ANIMATED]);
setAlign(props[Property_Constants.ALIGNMENT]);
setIsPlaying(props[Property_Constants.IS_PLAYING]);
setMultiTextChecked(props[Constants.MULTI_LINE_TEXT]);
setFitObject(props[Constants.OBJECT_FIT]);
setTempartureType(props[Property_Constants.TEMPERATURE_TYPE]);
setDDRInputEvents(props[Property_Constants.DDR_EVENTS]);
setNumStations(props[Property_Constants.NUM_STATIONS]);
setArrowIndex(props[Property_Constants.NUMBER_OF_ARROWS]);
}
const attachedFile = component.getCreatedFile();
if (attachedFile) {
setCreatedFile(attachedFile);
}
}, [component]);
useEffect(() => {
const retreiveAssets = async () => {
const styleAssets = (
await Repository.getInstance().getAssets(0, 0, "", AssetType.Style)
).items;
setStyleAssets(styleAssets);
const imageAssets = (
await Repository.getInstance().getAssets(0, 0, "", AssetType.Image)
).items;
setImageAssets(imageAssets);
const videoAssets = (
await Repository.getInstance().getAssets(0, 0, "", AssetType.Video)
).items;
setVideoAssets(videoAssets);
};
retreiveAssets();
}, []);
const setValue = (el: HTMLInputElement, value: number) => {
el.value = value.toString();
};
const animateChanged = (t: HTMLInputElement) => {
const newValue = t.checked;
setChecked(newValue);
const props = { ...extraProps, isAnimated: newValue };
setExtraProps(props);
component!.setExtraProps(props);
};
const multiLineChanged = (t: HTMLInputElement) => {
const newValue = t.checked;
setMultiTextChecked(newValue);
const props = { ...extraProps, multiLineText: newValue };
setExtraProps(props);
component!.setExtraProps(props);
};
const changeAnimationDirection = (t: React.ChangeEvent<HTMLInputElement>) => {
const newValue = t.target.value;
setDirection(newValue);
const props = { ...extraProps, direction: newValue };
setExtraProps(props);
component!.setExtraProps(props);
};
const handleTemperatureChange = (t: React.ChangeEvent<HTMLInputElement>) => {
const newValue = t.target.value;
const props = { ...extraProps, temperatureScales: newValue };
setTemperatureUnit(newValue);
setExtraProps(props);
component!.setExtraProps(props);
};
const handleDotOptionChange = (t: React.ChangeEvent<HTMLInputElement>) => {
const newValue = t.target.value;
setAnimatedDrmDotOptionValue(newValue);
const props = { ...extraProps, animatedDrmDotOptionValue: newValue };
setExtraProps(props);
component!.setExtraProps(props);
};
const handleFileUploadChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
const file = event.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
const uploadedFile = e.target?.result as string;
// Set uploaded file as background image
setArrowImage(uploadedFile);
};
reader.readAsDataURL(file);
}
};
const changeProp = (
propName: string,
propValue: string | number | boolean
) => {
const currentValue = extraProps[propName];
if (currentValue !== propValue) {
const props = { ...extraProps, [propName]: propValue };
setExtraProps(props);
component!.setExtraProps(props);
}
};
const propChanged = (e: ChangeEvent<HTMLInputElement>) => {
const propName = e.target.id.toString().substring(5);
const newValue =
typeof extraProps[propName] === "number"
? +e.target.value
: typeof extraProps[propName] === "boolean"
? e.target.checked
: e.target.value;
changeProp(propName, newValue);
};
const propChangedForTextarea = (e: ChangeEvent<HTMLTextAreaElement>) => {
const propName = e.target.id.toString().substring(5);
const newValue = e.target.value;
changeProp(propName, newValue);
};
const alignChanged = (e: ChangeEvent<HTMLInputElement>) => {
const propName = e.target.id.toString().split("-")[1];
const newValue = e.target.value;
setAlign(newValue);
changeProp(propName, newValue);
};
const changeInputDDREventState = (e: React.ChangeEvent<HTMLInputElement>) => {
const ddrValue = e.target.value;
const props = { ...extraProps, ddrEvents: ddrValue };
setDDRInputEvents(ddrValue);
setExtraProps(props);
component!.setExtraProps(props);
};
const changeComponetObjectFit = (e: React.ChangeEvent<HTMLInputElement>) => {
const targetValue = e.target.value;
const props = { ...extraProps, objectFit: targetValue };
setFitObject(targetValue);
setExtraProps(props);
component!.setExtraProps(props);
};
const handleStationChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// const newNumStations = +e.target.value;
const newNumStations = parseInt(e.target.value);
setNumStations(newNumStations);
// Ensure arrow index doesn't exceed the number of stations
setArrowIndex(Math.min(numberofArrows, newNumStations - 1));
const props = { ...extraProps, numStations: newNumStations };
setExtraProps(props);
component!.setExtraProps(props);
};
const handleArrowChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newArrowIndex = Number(e.target.value);
setArrowIndex(Math.max(0, Math.min(newArrowIndex, numStations - 1)));
const props = { ...extraProps, numberofArrows: newArrowIndex };
setExtraProps(props);
component!.setExtraProps(props);
};
const changeComponentAssetSelector = (
e: React.ChangeEvent<HTMLInputElement>,
assetType: string | undefined
) => {
let createdFile = {
name: "",
fileptr: Global_Constants.NOT_A_FP,
} as AttachCreatedFile;
let props = extraProps;
if (e.target.value === Global_Constants.NOT_A_FP) {
setCreatedFile(createdFile);
return;
}
if (assetType === AssetType.Style) {
const asset = styleAssets?.find((v) => v.file_pointer === e.target.value);
if (!asset) return;
props = { ...props, style: asset?.infoJson ?? "{}" };
createdFile = {
name: asset.name,
fileptr: asset.file_pointer,
} as AttachCreatedFile;
} else {
const asset =
assetType === AssetType.Image
? imageAssets?.find((v) => v.file_pointer === e.target.value)
: videoAssets?.find((v) => v.file_pointer === e.target.value);
if (!asset) return;
props = {
...extraProps,
src: `${config.assetsUrl}/${asset.file_pointer}`,
source: asset.name,
};
createdFile = {
name: asset.name,
fileptr: asset.file_pointer,
} as AttachCreatedFile;
if (assetType === AssetType.Video) {
const bounds = component!.getBounds();
const newSize = JSON.parse(asset.infoJson);
component!.setBounds({
...bounds,
width: newSize["width"],
height: newSize["height"],
});
}
}
setExtraProps(props);
component!.setExtraProps(props);
setCreatedFile(createdFile);
component!.setCreatedFile(createdFile);
};
function updateMultilanguage(locale: string, duration: any) {
let multiLanguage = JSON.parse(
String(extraProps[Property_Constants.MULTI_LANGUAGE])
);
multiLanguage = {
...multiLanguage,
[locale]: { ...multiLanguage[locale], duration: duration },
};
return multiLanguage;
}
const handleMultilingualCheckboxChange = (
e: any,
localecode: string,
sampleMessage: string
) => {
const sortedLocales = [...configuration.medialocales.locales].sort(
(a, b) => a.order - b.order
);
const allLocales = sortedLocales.map((item: any) => item.localecode);
let multiLanguage = JSON.parse(
String(extraProps[Property_Constants.MULTI_LANGUAGE])
);
const currentLocaleIndex = allLocales.indexOf(localecode);
for (
let index = currentLocaleIndex + 1;
index < allLocales.length;
index++
) {
const nextLocale = allLocales[index];
if (!e.target.checked) {
if (multiLanguage[nextLocale].checked) {
const nextLocaleDuration =
parseInt(multiLanguage[nextLocale][Property_Constants.DURATION]) +
parseInt(multiLanguage[localecode][Property_Constants.DURATION]);
multiLanguage = updateMultilanguage(nextLocale, nextLocaleDuration);
break;
}
} else {
if (multiLanguage[nextLocale].checked) {
let nextLocaleDuration =
parseInt(multiLanguage[nextLocale][Property_Constants.DURATION]) -
parseInt(multiLanguage[localecode][Property_Constants.DURATION]);
nextLocaleDuration = Math.max(nextLocaleDuration, 0);
multiLanguage = updateMultilanguage(nextLocale, nextLocaleDuration);
break;
}
}
}
multiLanguage = {
...multiLanguage,
[localecode]: {
...multiLanguage[localecode],
id: localecode,
sampleText: sampleMessage,
checked: e.target.checked,
},
};
const props = {
...extraProps,
[Property_Constants.MULTI_LANGUAGE]: JSON.stringify(multiLanguage),
};
setExtraProps(props);
component!.setExtraProps(props);
};
const handleDurationsInputChange = (
event: React.ChangeEvent<HTMLInputElement>,
locale: string
) => {
const { value } = event.target;
const multiLanguage = updateMultilanguage(locale, value);
const props = {
...extraProps,
[Property_Constants.MULTI_LANGUAGE]: JSON.stringify(multiLanguage),
};
setExtraProps(props);
component!.setExtraProps(props);
};
const onMultilanguageTextChanged = (e: ChangeEvent<HTMLTextAreaElement>) => {
const propName = e.target.id.toString().split("-")[1];
const newValue = e.target.value;
let multiLanguage = JSON.parse(
String(extraProps[Property_Constants.MULTI_LANGUAGE])
);
multiLanguage = {
...multiLanguage,
[propName]: {
id: propName,
sampleText: newValue,
checked: true,
duration: multiLanguage[propName][Property_Constants.DURATION],
},
};
const props = {
...extraProps,
[Property_Constants.MULTI_LANGUAGE]: JSON.stringify(multiLanguage),
};
setExtraProps(props);
component!.setExtraProps(props);
};
const toProperCase = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
const playPause = () => {
const newValue = !isPlaying;
setIsPlaying(newValue);
changeProp(Property_Constants.IS_PLAYING, newValue);
document
.getElementById("icon-play")!
.setAttribute("class", `fa fa-fw ${newValue ? "fa-pause" : "fa-play"}`);
};
const hiddenProps = [
Property_Constants.SOURCE,
Property_Constants.SRC,
Property_Constants.IS_PLAYING,
Constants.MULTI_LINE_TEXT,
Constants.OBJECT_FIT,
Property_Constants.TEMPERATURE_SCALES,
Property_Constants.INPUT_BOX,
];
const radioChanged = () => {
//
};
const alignmentInput = (p: string, propId: string): JSX.Element => {
return (
<WideGridItem className="px-2" key={p}>
<label>
{i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
toProperCase(p)}
</label>
<div onChange={alignChanged} className="d-flex justify-content-between">
<div>
<input
type="radio"
id={propId + "-left"}
value="left"
checked={align === "left"}
onChange={radioChanged}
/>
<i className="fa fa-align-left mx-1" />
</div>
<div>
<input
type="radio"
id={propId + "-center"}
value="center"
checked={align === "center"}
onChange={radioChanged}
/>
<i className="fa fa-align-center mx-1" />
</div>
<div>
<input
type="radio"
id={propId + "-right"}
value="right"
checked={align === "right"}
onChange={radioChanged}
/>
<i className="fa fa-align-right mx-1" />
</div>
</div>
</WideGridItem>
);
};
const styleInput = (p: string, propId: string): JSX.Element => (
<WideGridItem key="style">
<Label htmlFor="prop-source" accessKey="s">
{i18n(Global_Constants.GLOBAL, Global_Constants.STYLE)}
</Label>
<Input
type="select"
value={createdFile.fileptr}
onChange={(e) => changeComponentAssetSelector(e, AssetType.Style)}
id="comp-text-style-sel"
name="comp-text-style-sel"
title="Text Style selector"
className="comp-textStyle-select"
>
<option value="_not_a_fp__" key="non_comp-text-style-id">
{i18n(Global_Constants.SCENE_LOCALES, Constants.CHOOSE_STYLE)}
</option>
{styleAssets?.map((sa) => (
<option
key={`comp-text-style-id-${sa.file_pointer}`}
value={sa.file_pointer}
>
{sa.name}
</option>
))}
</Input>
</WideGridItem>
);
const DynamicField = (p: string) => {
const renderFields = () => {
const sortedLocales = [...configuration.medialocales.locales].sort(
(a, b) => a.order - b.order
);
const multiLanguageText = JSON.parse(String(extraProps[p]));
const inputBox = Boolean(extraProps.inputBox);
const fields = sortedLocales.map((item: any) => {
const { title, sampleText, localecode } = item;
const languageTextObj =
multiLanguageText && multiLanguageText[localecode]
? multiLanguageText[localecode]
: {
id: localecode,
sampleText: sampleText,
checked: true,
duration: "4",
};
if (!multiLanguageText[localecode]) {
multiLanguageText[localecode] = languageTextObj;
const props = {
...extraProps,
[p]: JSON.stringify(multiLanguageText),
};
setExtraProps(props);
component!.setExtraProps(props);
}
return getInputWithCheckboxComponent(
`${p}-${localecode}`,
`multilanguage-${localecode}`,
multiLanguageText[localecode].sampleText,
onMultilanguageTextChanged,
null,
multiLanguageText[localecode].checked,
title,
inputBox,
multiLanguageText[localecode].duration
);
});
return fields;
};
return <>{renderFields()}</>;
};
const handleDropdownChange = (
e: React.ChangeEvent<HTMLInputElement>,
component: any,
p: string,
index: number
) => {
const newValue = e.target.value;
const updatedDropdown = extraProps.dropdown.map(
(dropdownItem: any, idx: number) => {
if (idx === index) {
return { ...dropdownItem, selectedValue: newValue };
}
return dropdownItem;
}
);
const props = {
...extraProps,
dropdown: updatedDropdown,
};
setExtraProps(props);
component!.setExtraProps(props);
};
const createDropdown = (p: string, component: any) => {
const renderFields = () => {
if (!Array.isArray(extraProps.dropdown)) {
return null;
}
return extraProps.dropdown.map((dropdownItem: any, index: number) => {
const dropdownData: any =
Components[component.componentType].properties?.[dropdownItem.name];
const dropdownOptions = dropdownData?.options || [];
const selectedValue = dropdownItem.selectedValue;
return (
<WideGridItem key={index}>
<Label
htmlFor={`${component.componentType}${dropdownItem.name}Dropdown`}
>
{i18n(Global_Constants.SCENE_LOCALES, dropdownItem.name)}
</Label>
<Input
type="select"
onChange={(e) => handleDropdownChange(e, component, p, index)}
className="animation-direction text-capitalize"
value={selectedValue}
>
{dropdownOptions.map((value: any, idx: number) => (
<option key={idx} value={value}>
{value}
</option>
))}
</Input>
</WideGridItem>
);
});
};
return <>{renderFields()}</>;
};
const getInputWithCheckboxComponent = (
pElementkey: string,
propId: string,
inputValue: string,
onChangeHandler: any,
numberProps: any,
isChecked: boolean,
label: string,
inputBox: boolean,
duration: any
) => {
return (
<WideGridItem key={pElementkey}>
<Label htmlFor={propId} accessKey={PropNames[pElementkey]?.accessKey}>
{label
? label
: i18n(
Global_Constants.SCENE_LOCALES,
PropNames[pElementkey]?.displayText
) ?? toProperCase(pElementkey)}
<input
className="check-multilang"
id={propId}
key={`checkbox-${propId}`}
checked={isChecked}
onChange={(e) =>
handleMultilingualCheckboxChange(
e,
propId.split("-")[1],
inputValue
)
}
type="checkbox"
/>
{inputBox && (
<input
type="number"
id={`text-${propId}`}
key={`text-${propId}`}
min={0}
max={3600}
style={{
width: "50px",
border: "1px solid black",
borderRadius: "5px",
marginLeft: "5px",
marginBottom: "2px",
}}
value={duration}
onChange={(e) =>
handleDurationsInputChange(e, propId.split("-")[1])
}
/>
)}
</Label>
<WideTextArea
id={propId}
value={inputValue}
onChange={onChangeHandler}
{...numberProps}
/>
</WideGridItem>
);
};
const textInput = (
p: string,
propId: string,
inputType: string
): JSX.Element => {
let numberProps = {};
if (
component &&
component.componentType === Constants.COMPONENT_TYPE_MULTILINE_TEXT
) {
numberProps = { min: 1, max: 3 };
}
return propId === "prop-text" ? (
<WideGridItem key={p}>
<Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
{i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
toProperCase(p)}
</Label>
<WideTextArea
id={propId}
value={extraProps[p].toString()}
onChange={propChangedForTextarea}
{...numberProps}
/>
</WideGridItem>
) : propId === "prop-ddrEvents" ? (
<WideGridItem key={p}>
<Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
{i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
toProperCase(p)}
</Label>
<WideTextInput
id={propId}
value={ddrInputEvents}
placeholder={i18n(
Global_Constants.SCENE_LOCALES,
Constants.ENTER_DDR_VAR_NAMES
)}
onChange={changeInputDDREventState}
{...numberProps}
/>
</WideGridItem>
) : propId == "prop-numStations" ? (
<WideGridItem key={p}>
<Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
{i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
toProperCase(p)}
</Label>
<WideTextInput
id={propId}
type="number"
className="numarrows"
value={numStations}
min={2}
onChange={handleStationChange}
{...numberProps}
/>
</WideGridItem>
) : propId == "prop-numberofArrows" ? (
<WideGridItem key={p}>
<Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
{i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
toProperCase(p)}
</Label>
<WideTextInput
id={propId}
type="number"
value={numberofArrows}
className="numarrows"
max={numStations - 1}
min={0}
onChange={handleArrowChange}
{...numberProps}
/>
</WideGridItem>
) : propId !== "prop-direction" ? (
<WideGridItem key={p}>
<Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
{i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
toProperCase(p)}
</Label>
<WideTextInput
id={propId}
value={extraProps[p].toString()}
onChange={propChanged}
{...numberProps}
/>
</WideGridItem>
) : (
<></>
);
};
return component ? (
<Container>
<ComponentTitle>
{i18n(
Global_Constants.SCENE_LOCALES,
Components[component.componentType].displayName
)}
</ComponentTitle>
<GridItem>
<Label htmlFor="prop-x" accessKey="x">
x
</Label>
<TextInput
id="prop-x"
ref={refX}
onChange={dataChanged}
type="number"
/>
</GridItem>
<GridItem>
<Label htmlFor="prop-y" accessKey="y">
y
</Label>
<TextInput
id="prop-y"
ref={refY}
onChange={dataChanged}
type="number"
/>
</GridItem>
<GridItem>
<Label htmlFor="prop-width" accessKey="l">
{i18n(
Global_Constants.SEQUENCE_LOCALES,
PropNames["width"]?.displayText
) ?? "Width"}
</Label>
<TextInput
id="prop-width"
ref={refW}
onChange={dataChanged}
type="number"
readOnly={component.componentType === "Video"}
/>
</GridItem>
<GridItem>
<Label htmlFor="prop-height" accessKey="h">
{i18n(
Global_Constants.SEQUENCE_LOCALES,
PropNames["height"]?.displayText
) ?? "Height"}
</Label>
<TextInput
id="prop-height"
ref={refH}
onChange={dataChanged}
type="number"
/>
</GridItem>
{component && Components[component.componentType].canAnimate ? (
<WideGridItem className="form-check form-switch">
<input
className="form-check-input"
onChange={(e) => animateChanged(e.target)}
type="checkbox"
id="checkAnimate"
checked={checked}
/>
<label
className="form-check-label"
htmlFor="checkAnimate"
accessKey="a"
>
{i18n(Global_Constants.SCENE_LOCALES, Constants.ANIMATE)}
</label>
</WideGridItem>
) : (
<></>
)}
{Components[component.componentType].assetType ===
AssetType.AnimatedDrmDropdown ? (
<WideGridItem>
<Label htmlFor="animatedDrmDropdown" accessKey="d">
Line Style
</Label>
<Input
type="select"
onChange={(e) => handleDotOptionChange(e)}
className="animation-direction text-capitalize"
value={animatedDrmDotOptionValue}
>
{animatedDrmDotPosition.current.map((value, index) => (
<option key={index} value={value}>
{value}
</option>
))}
</Input>
</WideGridItem>
) : (
<></>
)}
{Components[component.componentType].assetNames ===
AssetNames.AT_DotsDropdown ? (
<WideGridItem>
<Label htmlFor="DotsDropdown" accessKey="d">
Arrow Type{" "}
</Label>
<input
type="file"
id="fileUpload"
onChange={handleFileUploadChange}
/>
</WideGridItem>
) : (
<></>
)}
{component && Components[component.componentType].canMultiLine ? (
<WideGridItem className="form-check form-switch">
<input
className="form-check-input"
onChange={(e) => multiLineChanged(e.target)}
type="checkbox"
id="multiLine"
checked={multiTextChecked}
/>
<label className="form-check-label" htmlFor="multiLine" accessKey="m">
{i18n(Global_Constants.SCENE_LOCALES, Constants.MULTI_LINE_TEXT)}
</label>
</WideGridItem>
) : (
<></>
)}
{extraProps &&
Object.keys(extraProps)
.filter((p) => p !== "isAnimated" && !hiddenProps.includes(p))
.map((p) => {
const inputType = p.toLowerCase().includes("color")
? "color"
: typeof extraProps[p] === "number"
? "number"
: "text";
const propId = `prop-${p}`;
return p.toLowerCase().includes("color") ? (
<ColorSelector
key={p}
propId={propId}
colorValue={extraProps[p].toString()}
onColorChanged={(c) => changeProp(p, c)}
component={component}
/>
) : typeof extraProps[p] === "boolean" ? (
<WideGridItem className="form-check form-switch" key={p}>
<input
className="form-check-input"
onChange={propChanged}
type="checkbox"
id={propId}
/>
<label
className="form-check-label"
htmlFor={propId}
accessKey={PropNames[p]?.accessKey}
>
{i18n(
Global_Constants.SCENE_LOCALES,
PropNames[p]?.displayText
) ?? toProperCase(p)}
</label>
</WideGridItem>
) : p.toLowerCase() === "alignment" ? (
alignmentInput(p, propId)
) : p.toLowerCase() === "style" ? (
styleInput(p, propId)
) : p.toLowerCase() === "direction" ? (
<WideGridItem>
<Label htmlFor={propId} accessKey="s">
{i18n(
Global_Constants.SCENE_LOCALES,
PropNames[p]?.displayText
) ?? toProperCase(p)}
</Label>
<Input
type="select"
onChange={(e) => changeAnimationDirection(e)}
id={propId}
name={propId}
className="animation-direction text-capitalize"
value={direction}
>
{directionOptional.current.map((value, index) => (
<option key={index} value={value}>
{value}
</option>
))}
</Input>
</WideGridItem>
) : p === "multilanguage" ? (
DynamicField(p)
) : p === "dropdown" ? (
createDropdown(p, component)
) : (
textInput(p, propId, inputType)
);
})}
{Components[component.componentType].assetType === "AT_Temprature" ? (
<WideGridItem key="Type">
<Label htmlFor="prop-Temperature" accessKey="t">
Type
</Label>
<Input
type="select"
onChange={(e) => handleTemperatureChange(e)}
id="prop-Temperature"
name="Temprature"
title="Type Temprature"
className="comp-temprature-select"
value={temperatureUnit}
>
{tempartureTypesOptions.current.map((item) => (
<option key={item} value={item}>
{item}
</option>
))}
</Input>
</WideGridItem>
) : (
Components[component.componentType].assetType &&
Components[component.componentType].assetType !==
AssetType.AnimatedDrmDropdown && (
<WideGridItem key="Source">
<Label htmlFor="prop-source" accessKey="s">
Source
</Label>
{showImageModal && (
<ThumbnailModal
show={showImageModal}
header="Select Resource"
onCloseModal={closeImageModal}
isOkVisible={false}
isCanVisible={true}
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
// eslint-disable-next-line @typescript-eslint/no-empty-function
// onOkClick={() => {}}
i18n={i18n}
>
<div
style={{
display: "flex",
flexWrap: "wrap",
overflowX: "hidden",
height: "100%",
width: "1100px",
minHeight: "600px",
minWidth: "1100px",
justifyContent: "center",
}}
>
{(Components[component.componentType].assetType ===
AssetType.Image
? imageAssets
: videoAssets
)
?.filter((asset) =>
asset.name
.toLowerCase()
.includes(searchQuery.toLowerCase())
)
.map((asset) => (
<div
style={{
padding: "5px",
justifyContent: "center",
alignItems: "center",
flex: "0 0 250px",
marginRight: "20px",
marginBottom: "20px",
border: "5px solid black",
height: "250px",
position: "relative",
display: "flex",
flexDirection: "column",
paddingTop: "15px",
}}
key={asset.file_pointer}
onClick={() => {
const syntheticEvent = {
target: { value: asset.file_pointer },
} as React.ChangeEvent<HTMLInputElement>;
changeComponentAssetSelector(
syntheticEvent,
Components[component.componentType].assetType ===
AssetType.Image
? AssetType.Image
: AssetType.Video
);
closeImageModal();
}}
>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100%",
}}
>
{Components[component.componentType].assetType ===
AssetType.Image ? (
<img
src={`${config.assetsUrl}/${asset.file_pointer}`}
alt={asset.name}
style={{
maxWidth: "150px",
maxHeight: "150px",
cursor: "pointer",
marginBottom: "10px",
alignSelf: "center",
}}
/>
) : (
<video
src={`${config.assetsUrl}/${asset.file_pointer}`}
style={{
maxWidth: "150px",
maxHeight: "150px",
cursor: "pointer",
marginBottom: "10px",
alignSelf: "center",
}}
/>
)}
</div>
<p
style={{
textAlign: "center",
marginTop: "auto",
marginBottom: "0",
backgroundColor: "#548b8b",
padding: "5px",
color: "white",
fontWeight: "bold",
height: "50px",
width: "100%",
overflow: "auto",
}}
>
{asset.name}
</p>
</div>
))}
</div>
</ThumbnailModal>
)}
<button className="btn btn-secondary" onClick={openImageModal}>
{i18n(Global_Constants.SCENE_LOCALES, Constants.SELECT_RESOURCE)}
</button>
</WideGridItem>
)
)}
{Components[component.componentType].assetType === AssetType.Image ? (
<WideGridItem key="Object-fit">
<Label htmlFor="prop-objectFit" accessKey="s">
{i18n(Global_Constants.SCENE_LOCALES, Constants.OBJECT_FIT)}
</Label>
<Input
type="select"
name="prop-objectFit"
id="prop-objectFit"
title="ObjectFit"
onChange={(e) => changeComponetObjectFit(e)}
value={fitObject}
className="text-capitalize"
>
{objectsFitOptions.current.map((item) => (
<option className="text-capitalize" key={item} value={item}>
{item}
</option>
))}
</Input>
</WideGridItem>
) : (
<></>
)}
{Components[component.componentType].assetType === AssetType.Video ? (
<WideGridItem>
<button className="btn btn-primary" onClick={playPause}>
<i className="fa fa-play fa-fw" id="icon-play" />
</button>
</WideGridItem>
) : (
<></>
)}
{onDeleteComponent && (
<GridItem>
<button
className="btn btn-primary"
onClick={() => onDeleteComponent(component.compId)}
>
<i className="fa fa-trash fa-fw" />
</button>
</GridItem>
)}
{onDuplicateComponent && (
<GridItem>
<button
className="btn btn-success"
onClick={() => onDuplicateComponent(component)}
>
<i className="fa fa-clone fa-fw" />
</button>
</GridItem>
)}
</Container>
) : (
<div>
{i18n(Global_Constants.SCENE_LOCALES, Constants.SELECT_COMPONENT)}
</div>
);
};