import * as React from "react"; import { get, head } from "lodash"; // import ReactJson from "react-json-view"; import ListItemIcon from "@material-ui/core/ListItemIcon"; // import CheckIcon from "@material-ui/icons/Check"; import CancelIcon from "@material-ui/icons/Cancel"; import IconButton from "@material-ui/core/IconButton"; import Menu from "@material-ui/core/Menu"; import MenuItem from "@material-ui/core/MenuItem"; import MoreVertIcon from "@material-ui/icons/MoreVert"; // import { LiveFormFieldProps } from "@sc/modules/v2/CRUD/FormBuilder/LiveFormField/types"; import { AttributeContainerProps, AttributeNames, AttributeList, } from "./types"; import IconSelector from "@sc/modules/v2/Properties/components/properties/IconSelector"; // import { fieldset } from "@sc/components/ui/theme"; import { Placeholder, Description, InitialValue, Label, FormItemName, Columns, Required, ValidationCriteria, } from "."; import { Grid, ListItemText } from "@material-ui/core"; import LinkSelector from "./LinkSelector"; import PresetSelector from "./PresetSelector"; /** * A component to use for displaying a consistent look and field for the collection of form fields * * - Pass in an array of attributes, and it will figure out where and how to display them * - It will collect and pass back the values as they are gathered */ const AttributeContainer: React.FC = ({ children, data = [], attributes = {}, hideFooter = false, style = {}, onChange = (data) => null, onBlur = (data) => null, }) => { const [liveData, setLiveData] = React.useState(data); const [anchorEl, setAnchorEl] = React.useState(null); const open = Boolean(anchorEl); /** * Converts the AttributeName enum into it's form field attribute counterpart * @param name AttributeNames */ const getAttributeKeyFromAttributeName = (name: AttributeNames): string => { switch (name) { case AttributeNames.COLUMNS: return "columns"; case AttributeNames.PLACEHOLDER: return "placeholder"; case AttributeNames.DESCRIPTION: return "description"; case AttributeNames.INITIALVALUE: return "defaultValue"; case AttributeNames.LABEL: return "label"; case AttributeNames.FORMITEMNAME: return "name"; case AttributeNames.REQUIRED: return "isRequired"; case AttributeNames.ICON: return "icon"; case AttributeNames.LINK: return "href"; case AttributeNames.PRESET: return "preset"; } }; /** * Combine any changes that come from the various attributes that I load and trigger the onChange prop * @params */ const handleChange = (type: AttributeNames, value: any): void => { const t = getAttributeKeyFromAttributeName(type); onChange({ ...attributes, [t]: value }); }; /** * Combine any changes that come from the various attributes that I load and trigger the onBlur prop * @params */ const handleBlur = (type: AttributeNames, value: any): void => { const t = getAttributeKeyFromAttributeName(type); onBlur({ ...attributes, [t]: value }); }; const handleShowHide = (option: AttributeList) => { const key = liveData.findIndex((itm) => itm.id === option.id); const newOption = { ...liveData[key], settings: { ...liveData[key].settings, hide: !liveData[key].settings.hide, }, }; // console.log({ option, liveData, newOption, key }); setLiveData([ ...liveData.slice(0, key), newOption, ...liveData.slice(key + 1), ]); setAnchorEl(null); }; const canIShow = ( attribute: AttributeNames, showIfHasAttributeValue = true ) => { const key = liveData.findIndex((itm) => itm.attribute === attribute); const attrValue = attributes[getAttributeKeyFromAttributeName(attribute)] || false; if (key > -1) { return ( !get(liveData[key], "settings.hide", false) || (attrValue.length && showIfHasAttributeValue) ); } }; const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; const getLabel = (name: AttributeNames) => { const item = data.filter((itm) => itm.attribute === name); return get(head(item), "settings.label", false); }; const getSetting = (name: AttributeNames, key: string) => { const item = data.filter((itm) => itm.attribute === name); return get(head(item), `settings.${key}`, false); }; React.useEffect(() => { setLiveData(data); }, [data]); return (
e.stopPropagation()} > {canIShow(AttributeNames.LABEL) && (
)} {canIShow(AttributeNames.PLACEHOLDER) && (
handleChange(AttributeNames.PLACEHOLDER, e)} onBlur={(e) => handleBlur(AttributeNames.PLACEHOLDER, e)} label={getLabel(AttributeNames.PLACEHOLDER)} value={get( attributes, getAttributeKeyFromAttributeName(AttributeNames.PLACEHOLDER) )} />
)} {canIShow(AttributeNames.DESCRIPTION) && (
handleChange(AttributeNames.DESCRIPTION, e)} onBlur={(e) => handleBlur(AttributeNames.DESCRIPTION, e)} label={getLabel(AttributeNames.DESCRIPTION)} value={get( attributes, getAttributeKeyFromAttributeName(AttributeNames.DESCRIPTION) )} />
)} {canIShow(AttributeNames.INITIALVALUE) && (
handleChange(AttributeNames.INITIALVALUE, e)} onBlur={(e) => handleBlur(AttributeNames.INITIALVALUE, e)} label={getLabel(AttributeNames.INITIALVALUE)} value={get( attributes, getAttributeKeyFromAttributeName(AttributeNames.INITIALVALUE) )} />
)} {canIShow(AttributeNames.FORMITEMNAME, false) && (
handleChange(AttributeNames.FORMITEMNAME, e)} onBlur={(e) => handleBlur(AttributeNames.FORMITEMNAME, e)} label={getLabel(AttributeNames.FORMITEMNAME)} value={get( attributes, getAttributeKeyFromAttributeName(AttributeNames.FORMITEMNAME) )} />
)} {canIShow(AttributeNames.LINK) && (
handleChange(AttributeNames.LINK, e)} onBlur={(e) => handleBlur(AttributeNames.LINK, e)} label={getLabel(AttributeNames.LINK)} data={getSetting(AttributeNames.LINK, "links")} value={get( attributes, getAttributeKeyFromAttributeName(AttributeNames.LINK) )} />
)} {canIShow(AttributeNames.PRESET) && (
handleChange(AttributeNames.PRESET, e)} onBlur={(e) => handleBlur(AttributeNames.PRESET, e)} label={getLabel(AttributeNames.PRESET)} data={getSetting(AttributeNames.PRESET, "presets")} value={get( attributes, getAttributeKeyFromAttributeName(AttributeNames.PRESET) )} />
)} {canIShow(AttributeNames.COLUMNS) && (
handleChange(AttributeNames.COLUMNS, e)} onBlur={(e) => handleBlur(AttributeNames.COLUMNS, e)} label={getLabel(AttributeNames.COLUMNS)} value={get( attributes, getAttributeKeyFromAttributeName(AttributeNames.COLUMNS) )} />
)} {canIShow(AttributeNames.ICON) && (
{ handleChange(AttributeNames.ICON, e); handleBlur(AttributeNames.ICON, e); }} isExpanded />
)} {children} {canIShow(AttributeNames.VALIDATIONCRITERIA) && (
{ handleChange(AttributeNames.VALIDATIONCRITERIA, e); handleBlur(AttributeNames.VALIDATIONCRITERIA, e); }} onBlur={(e) => handleBlur(AttributeNames.VALIDATIONCRITERIA, e)} label={getLabel(AttributeNames.VALIDATIONCRITERIA)} value={get( attributes, getAttributeKeyFromAttributeName( AttributeNames.VALIDATIONCRITERIA ) )} />
)} {!hideFooter && ( {canIShow(AttributeNames.REQUIRED) && (
{ handleChange(AttributeNames.REQUIRED, e); handleBlur(AttributeNames.REQUIRED, e); }} value={get( attributes, getAttributeKeyFromAttributeName(AttributeNames.REQUIRED) )} />
)}
{data .filter((itm) => get(itm, "settings.hide", false)) .map((option, key) => { const item = head( liveData.filter( (itm) => itm.attribute === option.attribute ) ); // const isShowing = get(item, "settings.hide", false); const isShowing = !canIShow(item.attribute); return ( handleShowHide(option)} > {isShowing ? (
) : ( )} ); })}
)}
); }; export default AttributeContainer;