\n );\n }\n });\n radios.push(\n
\n {Boolean(groupName !== '_ungrouped_') &&\n
\n {groupCollapseIcon}\n {groupName}\n
\n }\n
\n {groupOptions}\n
\n
\n );\n });\n\n //useRenderDebug('RadioGroupField', {props});\n\n return (\n
\n {radios}\n
\n );\n});\nRadioGroupField.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string.isRequired,\n value: PropTypes.oneOfType([\n PropTypes.number,\n PropTypes.string,\n PropTypes.bool,\n ]),\n options: PropTypes.arrayOf(\n PropTypes.shape({\n value: PropTypes.oneOfType([\n PropTypes.number,\n PropTypes.string,\n PropTypes.bool,\n ]),\n label: PropTypes.string,\n })\n ),\n autoFlex: PropTypes.bool,\n columns: PropTypes.number,\n datagroupAlias: PropTypes.string,\n enableCollapsibleGroups: PropTypes.bool,\n onChange: PropTypes.func,\n};\nRadioGroupField.defaultProps = {\n required: false,\n name: null,\n value: null,\n options: [],\n autoFlex: false,\n columns: 0,\n datagroupAlias: null,\n enableCollapsibleGroups: false,\n onChange: (name, value) => {},\n};\n\n//completed:\nconst SelectField = React.memo(function SelectField(props){\n const {\n isLoading,\n required,\n name,\n value,\n placeholder,\n emptyListText,\n showEmptyOption,\n options,\n datagroupAlias,\n onChange,\n } = props;\n const rootRef = React.useRef(null);\n\n const change = React.useCallback(event => {\n onChange(name, event.target.value);\n }, [name, onChange]);\n\n React.useEffect(() => {\n setTimeout(() => {\n if(rootRef.current) rootRef.current.dispatchEvent(new Event('parentchange'));\n }, 300);\n }, [value]);\n\n React.useEffect(() => {\n let allOptions = [];\n _.each(options, (options) => {\n allOptions = _.concat(allOptions, options.options);\n });\n if(_.size(allOptions) && !_.includes(_.map(allOptions, 'value'), value)){\n onChange(name, '');\n }\n }, [value, options]);\n\n let selectOptions = [];\n if(isLoading){\n selectOptions.push(\n
\n );\n }\n if(placeholder) {\n selectOptions.push(\n
\n );\n }\n\n if(showEmptyOption && _.size(options)){\n selectOptions.push(\n
\n );\n }\n\n _.each(options, (group, index) => {\n let groupName = group.group;\n if(groupName === '_ungrouped_'){\n _.each(group.options, (option, index) => {\n selectOptions.push(\n
\n );\n });\n }else{\n let groupOptions = [];\n _.each(group.options, (option, index) => {\n groupOptions.push(\n
\n );\n });\n selectOptions.push(\n
\n );\n }\n });\n\n //useRenderDebug('SelectField', {props});\n\n return (\n
\n );\n});\nSelectField.propTypes = {\n isLoading: PropTypes.bool,\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.oneOfType([\n PropTypes.number,\n PropTypes.string,\n PropTypes.bool,\n PropTypes.array,\n ]),\n placeholder: PropTypes.string,\n emptyListText: PropTypes.string,\n datagroupAlias: PropTypes.string,\n showEmptyOption: PropTypes.bool,\n options: PropTypes.arrayOf(\n PropTypes.shape({\n value: PropTypes.oneOfType([\n PropTypes.number,\n PropTypes.string,\n PropTypes.bool,\n ]),\n displayValue: PropTypes.string,\n disabled: PropTypes.bool,\n group: PropTypes.string,\n })\n ),\n onChange: PropTypes.func.isRequired,\n};\nSelectField.defaultProps = {\n isLoading: false,\n required: false,\n name: null,\n value: null,\n placeholder: null,\n emptyListText: 'No options available',\n showEmptyOption: true,\n options: [],\n datagroupAlias: null,\n onChange: (name, value) => {},\n};\n\n//completed:\nconst MultiSelectField = React.memo(function MultiSelectField(props){\n const {\n isLoading,\n required,\n name,\n multiMin,\n multiMax,\n value,\n placeholder,\n emptyListText,\n options: optionsFromProps,\n datagroupAlias,\n onChange,\n } = props;\n\n let multiselectRef = React.useRef(null);\n let selectRef = React.useRef(null);\n let inputRef = React.useRef(null);\n\n const [options, setOptions] = React.useState(optionsFromProps);\n const [visibleOptions, setVisibleOptions] = React.useState(optionsFromProps);\n const [optionListIsOpen, setOptionListIsOpen] = React.useState(false);\n const [hoveredOptionValue, setHoveredOptionValue] = React.useState(null);\n const [validationError, setValidationError] = React.useState(\"\");\n const [allOptions, setAllOptions] = React.useState([]);\n const [allVisibleOptions, setAllVisibleOptions] = React.useState([]);\n\n const handleChange = React.useCallback((event) => {\n let values = [];\n let options = event.target.options;\n for (let i = 0, length = options.length; i < length; i++) {\n if (options[i].selected) {\n values.push(options[i].value);\n }\n }\n onChange(name, values);\n }, [onChange, name]);\n\n const handleCustomChange = React.useCallback(selectedValue => event => {\n let values = _.clone(value);\n if(_.indexOf(values, selectedValue) < 0){\n values.push(selectedValue);\n }else{\n _.remove(values, (value) => value === selectedValue);\n }\n onChange(name, values);\n }, [onChange, value, name]);\n\n const handleRemove = React.useCallback(valueToRemove => event => {\n let values = _.clone(value);\n _.remove(values, (value) => value === valueToRemove);\n onChange(name, values);\n event.stopPropagation();\n event.preventDefault();\n return false;\n }, [onChange, value, name]);\n\n const hoverOption = React.useCallback((direction) => {\n setHoveredOptionValue(hoveredOption => {\n let nextIndex = null;\n if(!hoveredOption){\n if(direction === 'next') nextIndex = 0;\n if(direction === 'prev') nextIndex = _.size(allVisibleOptions) - 1;\n }else{\n if(direction === 'next'){\n nextIndex = _.findIndex(allVisibleOptions, {value: hoveredOption}) + 1;\n if(nextIndex === _.size(allVisibleOptions)) nextIndex = 0;\n }\n if(direction === 'prev'){\n nextIndex = _.findIndex(allVisibleOptions, {value: hoveredOption}) - 1;\n if(nextIndex < 0) nextIndex = _.size(allVisibleOptions) - 1;\n }\n }\n return allVisibleOptions[nextIndex].value\n });\n }, [allVisibleOptions]);\n\n const onInputClick = React.useCallback((event) => {\n setOptionListIsOpen(optionListIsOpen => !optionListIsOpen);\n }, []);\n\n const onInputKeyDown = React.useCallback((event) => {\n switch(event.which) {\n case 27: //Tab\n if(optionListIsOpen) setOptionListIsOpen(false);\n return;\n case 9: //Esc\n if(optionListIsOpen) setOptionListIsOpen(false);\n return;\n case 38: //Up\n if(!optionListIsOpen) setOptionListIsOpen(true);\n if(optionListIsOpen) hoverOption('prev');\n event.preventDefault();\n return;\n case 40: //Down\n if(!optionListIsOpen) setOptionListIsOpen(true);\n if(optionListIsOpen) hoverOption('next');\n event.preventDefault();\n return;\n case 32: //Space\n if(optionListIsOpen && hoveredOptionValue) {\n handleCustomChange(hoveredOptionValue)();\n event.preventDefault();\n }\n return;\n case 13: //Enter\n if(optionListIsOpen && hoveredOptionValue) {\n handleCustomChange(hoveredOptionValue)();\n event.preventDefault();\n }\n return;\n default:\n return;\n }\n }, [optionListIsOpen, hoveredOptionValue, hoverOption]);\n\n const onSearchInputKeyDown = React.useCallback(event => {\n switch(event.which) {\n case 27: //Esc\n if(optionListIsOpen) setOptionListIsOpen(false);\n return;\n case 9: //Tab\n if(optionListIsOpen) {\n inputRef.current.focus();\n hoverOption('next');\n }\n event.preventDefault();\n return;\n default:\n return;\n }\n }, [optionListIsOpen]);\n\n const onSearchInputKeyUp = React.useCallback(event => {\n let keyword = event.target.value.toLowerCase();\n if(Boolean(keyword.length)){\n let filteredOptionsObject = {};\n _.each(options, ({group: groupName, options: groupOptions}) => {\n _.each(groupOptions, option => {\n if(_.includes(groupName.toLowerCase(), keyword) || _.includes(option.displayValue.toLowerCase(), keyword)){\n if(!filteredOptionsObject[groupName]){\n filteredOptionsObject[groupName] = [];\n }\n filteredOptionsObject[groupName].push(option);\n }\n });\n });\n\n let filteredOptions = [];\n _.each(filteredOptionsObject, (groupOptions, groupName) => {\n filteredOptions.push({\n group: groupName,\n options: groupOptions,\n });\n });\n\n setVisibleOptions(filteredOptions);\n }else{\n setVisibleOptions(options);\n }\n }, [optionListIsOpen, options]);\n\n const onOptionHover = React.useCallback(optionValue => event => {\n setHoveredOptionValue(optionValue);\n }, []);\n\n useOnClickOutside(multiselectRef, () => setOptionListIsOpen(false));\n\n React.useEffect(() => {\n setOptions(optionsFromProps);\n setVisibleOptions(optionsFromProps);\n }, [optionsFromProps]);\n\n React.useEffect(() => {\n selectRef.current.dispatchEvent(new Event('parentchange'));\n }, [value]);\n\n React.useEffect(() => {\n let validationError = '';\n if (required && !_.size(value)) {\n validationError = `Please select an item in the list`;\n } else if (multiMin && _.size(value) && _.size(value) < multiMin) {\n validationError = `You need to select at least ${multiMin} options`;\n } else if (multiMax && _.size(value) && _.size(value) > multiMax) {\n validationError = `You need to select maximum ${multiMax} options`;\n }\n\n setValidationError(validationError);\n selectRef.current.setCustomValidity(validationError);\n }, [required, value, multiMin, multiMax]);\n\n React.useEffect(() => {\n let tmp = [];\n _.each(options, (options) => {\n tmp = _.concat(tmp, options.options);\n });\n setAllOptions(tmp);\n }, [options]);\n\n React.useEffect(() => {\n let tmp = [];\n _.each(visibleOptions, (options) => {\n tmp = _.concat(tmp, options.options);\n });\n setAllVisibleOptions(tmp);\n }, [visibleOptions]);\n\n let placeholderText = null;\n let nativeOptions = [];\n let customOptions = [];\n if(placeholder) {\n placeholderText = placeholder;\n }\n if(isLoading){\n placeholderText = 'Loading...';\n }\n if(_.size(value)){\n placeholderText = null;\n }\n\n if(emptyListText && !_.size(allOptions)){\n nativeOptions.push(\n
\n );\n }\n\n _.each(visibleOptions, (group, index) => {\n let groupName = group.group;\n if(groupName === '_ungrouped_'){\n _.each(group.options, (option, index) => {\n nativeOptions.push(\n
\n );\n customOptions.push(\n
-1 ? 'checked' : ''} ${hoveredOptionValue === option.value ? 'hovered' : ''}`}\n key={`option-${index}`}\n onClick={handleCustomChange(option.value)}\n onMouseEnter={onOptionHover(option.value)}\n onMouseLeave={onOptionHover(null)}\n >\n \n {option.displayValue}\n
\n );\n });\n }else{\n let groupNativeOptions = [];\n let groupCustomOptions = [];\n _.each(group.options, (option, index) => {\n groupNativeOptions.push(\n
\n );\n groupCustomOptions.push(\n
-1 ? 'checked' : ''} ${hoveredOptionValue === option.value ? 'hovered' : ''}`}\n key={`option-${groupName}-${index}`}\n onClick={handleCustomChange(option.value)}\n onMouseEnter={onOptionHover(option.value)}\n onMouseLeave={onOptionHover(null)}\n >\n \n {option.displayValue}\n
\n );\n });\n nativeOptions.push(\n
\n );\n customOptions.push(\n
\n
{groupName}
\n {groupCustomOptions}\n
\n );\n }\n });\n\n let optionTags = [];\n _.each(value, (val) => {\n let selectedTag = _.find(allOptions, option => {return option.value === val});\n if(selectedTag) {\n optionTags.push(\n
\n {selectedTag.displayValue}\n \n
\n );\n }\n });\n\n let showSearchField = _.size(allOptions) > 20;\n\n //useRenderDebug('MultiSelectField', {props, optionListIsOpen, hoveredOptionValue, validationError, handleChange, handleCustomChange, handleRemove, hoverOption, onInputClick, onInputKeyDown, onOptionHover});\n\n return (\n
\n
\n
0 ? validationError : null}\n />\n
{optionTags}
\n {!isMobile() &&\n
\n {showSearchField &&\n
\n \n
\n }\n {customOptions}\n
\n }\n
\n );\n});\nMultiSelectField.propTypes = {\n isLoading: PropTypes.bool,\n required: PropTypes.bool,\n name: PropTypes.string,\n multiMin: PropTypes.number,\n multiMax: PropTypes.number,\n value: PropTypes.array,\n placeholder: PropTypes.string,\n emptyListText: PropTypes.string,\n options: PropTypes.arrayOf(\n PropTypes.shape({\n value: PropTypes.string,\n displayValue: PropTypes.string,\n disabled: PropTypes.bool,\n group: PropTypes.string,\n })\n ),\n datagroupAlias: PropTypes.string,\n onChange: PropTypes.func.isRequired,\n};\nMultiSelectField.defaultProps = {\n isLoading: false,\n required: false,\n name: null,\n multiMin: null,\n multiMax: null,\n value: [],\n placeholder: null,\n emptyListText: 'No options available',\n options: [],\n datagroupAlias: null,\n onChange: (name, value) => {},\n};\n\n//=======================================================================\n// FIELD TYPES ==========================================================\n//=======================================================================\n\n//completed:\nconst TaskFormFieldTypeText = React.memo(function TaskFormFieldTypeText(props){\n const {\n required,\n value,\n name,\n placeholder,\n minLength,\n maxLength,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeText', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeText.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n minLength: PropTypes.number,\n maxLength: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeText.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n minLength: null,\n maxLength: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeText.displayName = 'FieldType: Text';\n\n//completed:\nconst TaskFormFieldTypeCheckbox = React.memo(function TaskFormFieldTypeCheckbox(props){\n const {\n required,\n name,\n checked,\n boxLabel,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeCheckbox', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeCheckbox.propTypes = {\n name: PropTypes.string,\n required: PropTypes.bool,\n checked: PropTypes.bool,\n boxLabel: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeCheckbox.defaultProps = {\n name: '',\n required: false,\n checked: false,\n boxLabel: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeCheckbox.displayName = 'FieldType: Checkbox';\n\n//completed:\nconst TaskFormFieldTypeBoolean = React.memo(function TaskFormFieldTypeBoolean(props){\n const {\n required,\n name,\n value,\n onChange,\n yesLabel,\n noLabel,\n indexFromParent,\n } = props;\n\n const options = React.useRef([{\n group: '_ungrouped_',\n options: [{\n value: true,\n label: yesLabel,\n }, {\n value: false,\n label: noLabel,\n }]\n }]);\n\n //useRenderDebug('TaskFormFieldTypeBoolean', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeBoolean.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.bool,\n yesLabel: PropTypes.string,\n noLabel: PropTypes.string,\n indexFromParent: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeBoolean.defaultProps = {\n required: false,\n name: '',\n value: null,\n yesLabel: 'Yes',\n noLabel: 'No',\n indexFromParent: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeBoolean.displayName = 'FieldType: Boolean';\n\n//completed:\nconst TaskFormFieldTypeYesNo = React.memo(function TaskFormFieldTypeYesNo(props){\n const {\n required,\n name,\n value,\n yesLabel,\n noLabel,\n showYesExplanation,\n showNoExplanation,\n yesExplanationLabel,\n noExplanationLabel,\n yesExplanationRequired,\n noExplanationRequired,\n yesMaxChars,\n noMaxChars,\n indexFromParent,\n onChange,\n } = props;\n\n const onOptionChange = React.useCallback((n, v) => {\n let newValue = _.clone(value);\n _.set(newValue, 'option', v);\n _.set(newValue, 'explanation', value.option === v ? value.explanation : '');\n onChange(name, newValue);\n }, [name, value]);\n\n const onExplanationChange = React.useCallback((n, v) => {\n let newValue = _.clone(value);\n _.set(newValue, 'explanation', v);\n onChange(name, newValue);\n }, [name, value]);\n\n let explanationField = null;\n if(value.option !== null && (value.option === 1 && showYesExplanation || value.option === 0 && showNoExplanation)){\n explanationField = (\n
\n );\n }\n\n const options = React.useRef({\n group: '_ungrouped_',\n options: [{\n value: 1,\n label: yesLabel,\n }, {\n value: 0,\n label: noLabel,\n }]\n });\n\n //useRenderDebug('TaskFormFieldTypeYesNo', {props});\n\n return (\n
\n \n {explanationField}\n
\n );\n});\nTaskFormFieldTypeYesNo.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.object,\n yesLabel: PropTypes.string,\n noLabel: PropTypes.string,\n showYesExplanation: PropTypes.bool,\n showNoExplanation: PropTypes.bool,\n yesExplanationLabel: PropTypes.string,\n noExplanationLabel: PropTypes.string,\n yesExplanationRequired: PropTypes.bool,\n noExplanationRequired: PropTypes.bool,\n yesMaxChars: PropTypes.number,\n noMaxChars: PropTypes.number,\n indexFromParent: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeYesNo.defaultProps = {\n required: false,\n name: '',\n value: {\n option: null,\n explanation: ''\n },\n yesLabel: 'Yes',\n noLabel: 'No',\n showYesExplanation: false,\n showNoExplanation: false,\n yesExplanationLabel: 'Explain',\n noExplanationLabel: 'Explain',\n yesExplanationRequired: false,\n noExplanationRequired: false,\n yesMaxChars: null,\n noMaxChars: null,\n indexFromParent: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeYesNo.displayName = 'FieldType: YesNo';\n\n//completed:\nconst TaskFormFieldTypeDate = React.memo(function TaskFormFieldTypeDate(props){\n const {\n required,\n name,\n value,\n placeholder,\n minValue,\n maxValue,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeDate', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeDate.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n minValue: PropTypes.string,\n maxValue: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeDate.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n minValue: null,\n maxValue: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeDate.displayName = 'FieldType: Date';\n\n//completed:\nconst TaskFormFieldTypeTime = React.memo(function TaskFormFieldTypeTime(props){\n const {\n required,\n value,\n name,\n placeholder,\n minValue,\n maxValue,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeTime', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeTime.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n minValue: PropTypes.string,\n maxValue: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeTime.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n minValue: null,\n maxValue: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeTime.displayName = 'FieldType: Time';\n\n//completed:\nconst TaskFormFieldTypeDecimal = React.memo(function TaskFormFieldTypeDecimal(props){\n const {\n required,\n value,\n name,\n placeholder,\n minValue,\n maxValue,\n step,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeDecimal', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeDecimal.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n minValue: PropTypes.number,\n maxValue: PropTypes.number,\n step: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeDecimal.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n minValue: null,\n maxValue: null,\n step: 0.1,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeDecimal.displayName = 'FieldType: Decimal';\n\n//completed:\nconst TaskFormFieldTypeNumber = React.memo(function TaskFormFieldTypeNumber(props){\n const {\n required,\n value,\n name,\n placeholder,\n minValue,\n maxValue,\n step,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeNumber', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeNumber.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n minValue: PropTypes.number,\n maxValue: PropTypes.number,\n step: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeNumber.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n minValue: null,\n maxValue: null,\n step: 1,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeNumber.displayName = 'FieldType: Number';\n\n//completed:\nconst TaskFormFieldTypeTextArea = React.memo(function TaskFormFieldTypeTextArea(props){\n const {\n required,\n value,\n name,\n placeholder,\n minLength,\n maxLength,\n rows,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeTextArea', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeTextArea.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n minLength: PropTypes.number,\n maxLength: PropTypes.number,\n rows: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeTextArea.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n minLength: null,\n maxLength: null,\n rows: 4,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeTextArea.displayName = 'FieldType: TextArea';\n\n//completed:\nconst TaskFormFieldTypeHtml = React.memo(function TaskFormFieldTypeHtml(props){\n const {\n required,\n value,\n name,\n placeholder,\n maxLength,\n rows,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeHtml', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeHtml.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n maxLength: PropTypes.number,\n rows: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeHtml.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n maxLength: null,\n rows: 4,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeHtml.displayName = 'FieldType: Html';\n\n//completed:\nconst TaskFormFieldTypeTextBox = React.memo(function TaskFormFieldTypeTextBox(props){\n const {\n value,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeTextBox', {props});\n\n if(!value) return null;\n\n return (\n
\n );\n});\nTaskFormFieldTypeTextBox.propTypes = {\n value: PropTypes.string,\n};\nTaskFormFieldTypeTextBox.defaultProps = {\n value: null,\n};\nTaskFormFieldTypeTextBox.displayName = 'FieldType: Text Box';\n\n//completed:\nconst TaskFormFieldTypeSelect = React.memo(function TaskFormFieldTypeSelect(props){\n const {\n renderAs,\n url,\n store,\n required,\n name,\n value,\n idPath,\n displayPath,\n groupPath,\n missingGroupingValue,\n enableCollapsibleGroups,\n placeholder,\n emptyListText,\n columns,\n autoFlexColumns,\n isMulti,\n multiMin,\n multiMax,\n onChange,\n } = props;\n\n const [isLoading, options] = useAjaxLoader(url, idPath, displayPath, groupPath, missingGroupingValue);\n\n let FieldClass = SelectField;\n if(renderAs === 'multiselect') FieldClass = MultiSelectField;\n if(renderAs === 'radiogroup') FieldClass = RadioGroupField;\n if(renderAs === 'checkboxgroup') FieldClass = CheckboxGroupField;\n\n let parsedValue = value;\n if(_.includes(['multiselect', 'checkboxgroup'], renderAs)){\n parsedValue = _.filter(parsedValue, val => {return val !== null});\n }\n\n //useRenderDebug('TaskFormFieldTypeSelect', {props});\n\n if(store){\n let parsedStore = groupOptions(store, idPath, displayPath, groupPath, missingGroupingValue);\n\n return (\n
\n );\n }\n\n return (\n
\n );\n});\nTaskFormFieldTypeSelect.propTypes = {\n renderAs: PropTypes.oneOf(['select', 'combo', 'multiselect', 'radiogroup', 'checkboxgroup']),\n url: PropTypes.string,\n store: PropTypes.array,\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.any,\n idPath: PropTypes.string.isRequired,\n displayPath: PropTypes.string.isRequired,\n groupPath: PropTypes.string,\n missingGroupingValue: PropTypes.string,\n enableCollapsibleGroups: PropTypes.bool,\n placeholder: PropTypes.string,\n emptyListText: PropTypes.string,\n columns: PropTypes.number,\n autoFlexColumns: PropTypes.bool,\n isMulti: PropTypes.bool,\n multiMin: PropTypes.number,\n multiMax: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeSelect.defaultProps = {\n renderAs: 'select',\n url: null,\n store: null,\n required: false,\n name: '',\n value: '',\n idPath: 'id',\n displayPath: null,\n groupPath: null,\n missingGroupingValue: 'Other',\n enableCollapsibleGroups: false,\n emptyListText: 'No Records',\n placeholder: null,\n columns: null,\n autoFlexColumns: true,\n isMulti: false,\n multiMin: null,\n multiMax: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeSelect.displayName = 'FieldType: Select';\n\n//completed:\nconst TaskFormFieldTypeDatagroup = React.memo(function TaskFormFieldTypeDatagroup(props){\n const {\n renderAs,\n required,\n value,\n name,\n idPath,\n displayPath,\n groupPath,\n placeholder,\n emptyListText,\n datagroupAlias,\n datagroupParentAlias,\n parentFilterBy,\n orderBy,\n orderDirection,\n columns,\n autoFlexColumns,\n isMulti,\n multiMin,\n multiMax,\n indexFromParent,\n onChange,\n } = props;\n\n const [url, setUrl] = React.useState(null);\n const [parentDatagroup, setParentDatagroup] = React.useState(null);\n const [parentDatagroupValue, setParentDatagroupValue] = React.useState(null);\n const [isLoading, options] = useAjaxLoader(url, idPath, displayPath, groupPath);\n\n const onParentChange = React.useCallback(event => {\n let value = Boolean(event.target.dataset.value) ? event.target.dataset.value : null;\n setParentDatagroupValue(value);\n }, [onChange]);\n\n React.useEffect(() => {\n let url = [`/p/Datagroups/admin/DatagroupValues/getAll.json?datagroup_alias=${datagroupAlias}&deleted=0&normalize=1`];\n if(orderBy){\n let order = JSON.stringify([{property: orderBy, direction: orderDirection}]);\n url.push(`sort=${order}`);\n }\n if(parentFilterBy){\n let filter = JSON.stringify([{property: parentFilterBy, value: _.split(parentDatagroupValue, ',')}]);\n url.push(`filter=${filter}`);\n }\n if(parentFilterBy && !Boolean(parentDatagroupValue)) {\n url = null;\n }\n if(url) url = _.join(url, '&');\n\n setUrl(url);\n }, [datagroupAlias, orderBy, orderDirection, parentFilterBy, parentDatagroup, parentDatagroupValue]);\n\n React.useEffect(() => {\n if(datagroupParentAlias){\n let el = document.querySelector(`*[data-datagroup-alias=\"${datagroupParentAlias}-${indexFromParent}\"]`);\n setParentDatagroup(el);\n if(el){\n el.addEventListener('parentchange', onParentChange);\n return () => {\n el.removeEventListener('parentchange', onParentChange);\n }\n }\n }\n }, [datagroupParentAlias]);\n\n let FieldClass = SelectField;\n if(renderAs === 'multiselect') FieldClass = MultiSelectField;\n if(renderAs === 'radiogroup') FieldClass = RadioGroupField;\n if(renderAs === 'checkboxgroup') FieldClass = CheckboxGroupField;\n\n let parsedValue = value;\n if(_.includes(['multiselect', 'checkboxgroup'], renderAs)){\n parsedValue = _.filter(parsedValue, val => {return val !== null});\n }\n\n // useRenderDebug(`TaskFormFieldTypeDatagroup|${name}`, {props, url, parentDatagroup, parentDatagroupValue, isLoading, options});\n\n return (\n
\n );\n});\nTaskFormFieldTypeDatagroup.propTypes = {\n renderAs: PropTypes.oneOf(['combo', 'multiselect', 'radiogroup', 'checkboxgroup']),\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.any,\n idPath: PropTypes.string.isRequired,\n displayPath: PropTypes.string.isRequired,\n groupPath: PropTypes.string,\n placeholder: PropTypes.string,\n emptyListText: PropTypes.string,\n datagroupAlias: PropTypes.string.isRequired,\n datagroupParentAlias: PropTypes.string,\n parentFilterBy: PropTypes.string,\n orderBy: PropTypes.string,\n orderDirection: PropTypes.oneOf(['asc', 'desc']),\n columns: PropTypes.number,\n autoFlexColumns: PropTypes.bool,\n isMulti: PropTypes.bool,\n multiMin: PropTypes.number,\n multiMax: PropTypes.number,\n indexFromParent: PropTypes.number,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeDatagroup.defaultProps = {\n renderAs: 'combo',\n required: false,\n name: '',\n value: '',\n idPath: 'id',\n displayPath: null,\n groupPath: null,\n emptyListText: 'No Records',\n datagroupAlias: null,\n datagroupParentAlias: null,\n parentFilterBy: null,\n orderBy: null,\n orderDirection: 'asc',\n placeholder: null,\n columns: null,\n autoFlexColumns: true,\n isMulti: false,\n multiMin: null,\n multiMax: null,\n indexFromParent: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeDatagroup.displayName = 'FieldType: Datagroup';\n\n//completed:\nconst TaskFormFieldTypeEmail = React.memo(function TaskFormFieldTypeEmail(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeEmail', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeEmail.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeEmail.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeEmail.displayName = 'FieldType: Email';\n\n//completed:\nconst TaskFormFieldTypeBirthday = React.memo(function TaskFormFieldTypeBirthday(props){\n const {\n required,\n name,\n value,\n placeholder,\n minValue,\n maxValue,\n onChange,\n } = props;\n\n //useRenderDebug('TaskFormFieldTypeBirthday', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeBirthday.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n minValue: PropTypes.string,\n maxValue: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeBirthday.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n minValue: null,\n maxValue: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeBirthday.displayName = 'FieldType: Birthday';\n\n//completed:\nconst TaskFormFieldTypeGender = React.memo(function TaskFormFieldTypeGender(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n let options = React.useRef([{\n group: \"_ungrouped_\",\n options: [{\n value: 'm',\n displayValue: 'Male',\n }, {\n value: 'f',\n displayValue: 'Female',\n }]\n }]);\n\n //useRenderDebug('TaskFormFieldTypeGender', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeGender.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeGender.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeGender.displayName = 'FieldType: Gender';\n\n//completed:\nconst TaskFormFieldTypeEmailType = React.memo(function TaskFormFieldTypePhoneType(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const [isLoading, options] = useAjaxLoader('/p/People/admin/PersonEmailTypes/getAll.json', 'id', 'label');\n\n //useRenderDebug('TaskFormFieldTypePhoneType', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeEmailType.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.any,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeEmailType.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeEmailType.displayName = 'FieldType: Email Type';\n\n//completed:\nconst TaskFormFieldTypeAddressCountry = React.memo(function TaskFormFieldTypeAddressCountry(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const [isLoading, options] = useAjaxLoader('/p/Locations/admin/LocationCountries/getAll.json?sort=name', 'id', 'name');\n\n //useRenderDebug('TaskFormFieldTypeAddressCountry', {props, isLoading, options});\n\n return (\n
\n );\n});\nTaskFormFieldTypeAddressCountry.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.any,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeAddressCountry.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeAddressCountry.displayName = 'FieldType: Address Country';\n\n//completed:\nconst TaskFormFieldTypeAddressState = React.memo(function TaskFormFieldTypeAddressState(props){\n const {\n countryId,\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const previousCountryId = React.useRef(countryId);\n const [isLoading, options] = useAjaxLoader(countryId ? `/p/Locations/admin/LocationStates/getAll.json?sort=name&location_country_id=${countryId}` : null, 'id', 'name');\n\n React.useEffect(() => {\n if (!countryId) {\n onChange(name, previousCountryId.current !== null && previousCountryId.current !== countryId ? null : value);\n }\n if (countryId !== previousCountryId.current) {\n previousCountryId.current = countryId;\n }\n }, [countryId]);\n\n //useRenderDebug('TaskFormFieldTypeAddressState', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeAddressState.propTypes = {\n countryId: PropTypes.any,\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.any,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeAddressState.defaultProps = {\n countryId: null,\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeAddressState.displayName = 'FieldType: Address State';\n\n//completed:\nconst TaskFormFieldTypeAddressType = React.memo(function TaskFormFieldTypeAddressType(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const [isLoading, options] = useAjaxLoader('/p/People/admin/PersonAddressTypes/getAll.json', 'id', 'label');\n\n //useRenderDebug('TaskFormFieldTypeAddressType', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeAddressType.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.any,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeAddressType.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeAddressType.displayName = 'FieldType: Address Type';\n\n//completed:\nconst TaskFormFieldTypePhoneDefault = React.memo(function TaskFormFieldTypePhoneDefault(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const change = React.useCallback((n, v) => {\n onChange(name, v === '1');\n }, [onChange, name]);\n\n const options = React.useRef([{\n group: \"_ungrouped_\",\n options: [{\n value: '1',\n displayValue: 'Yes',\n }, {\n value: '0',\n displayValue: 'No',\n }]\n }]);\n\n //useRenderDebug('TaskFormFieldTypePhoneDefault', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypePhoneDefault.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.any,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypePhoneDefault.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypePhoneDefault.displayName = 'FieldType: Phone Default';\n\n//completed:\nconst TaskFormFieldTypePhoneType = React.memo(function TaskFormFieldTypePhoneType(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const [isLoading, options] = useAjaxLoader('/p/People/admin/PersonPhoneTypes/getAll.json', 'id', 'label');\n\n //useRenderDebug('TaskFormFieldTypePhoneType', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypePhoneType.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.any,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypePhoneType.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypePhoneType.displayName = 'FieldType: Phone Type';\n\n//completed:\nconst TaskFormFieldTypeInstantMessengerType = React.memo(function TaskFormFieldTypeInstantMessengerType(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const [isLoading, options] = useAjaxLoader('/p/People/admin/PersonInstantMessengerTypes/getAll.json', 'id', 'label');\n\n //useRenderDebug('TaskFormFieldTypeInstantMessengerType', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeInstantMessengerType.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeInstantMessengerType.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeInstantMessengerType.displayName = 'FieldType: Instant Messenger Type';\n\n//completed:\nconst TaskFormFieldTypeSocialNetworkType = React.memo(function TaskFormFieldTypeSocialNetworkType(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const [isLoading, options] = useAjaxLoader('/p/People/admin/PersonSocialMediaTypes/getAll.json', 'id', 'label');\n\n //useRenderDebug('TaskFormFieldTypeSocialNetworkType', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeSocialNetworkType.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeSocialNetworkType.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeSocialNetworkType.displayName = 'FieldType: Social Network Type';\n\n//completed:\nconst TaskFormFieldTypeHouseholdMember = React.memo(function TaskFormFieldTypeHouseholdMember(props){\n const {\n required,\n value,\n name,\n placeholder,\n onChange,\n } = props;\n\n const [isLoading, options] = useAjaxLoader('/p/People/People/getHouseholdMembers.json', 'id', 'fullname');\n\n //useRenderDebug('TaskFormFieldTypeSocialNetworkType', {props});\n\n return (\n
\n );\n});\nTaskFormFieldTypeHouseholdMember.propTypes = {\n required: PropTypes.bool,\n name: PropTypes.string,\n value: PropTypes.string,\n placeholder: PropTypes.string,\n onChange: PropTypes.func,\n};\nTaskFormFieldTypeHouseholdMember.defaultProps = {\n required: false,\n name: '',\n value: '',\n placeholder: null,\n onChange: (name, value) => {},\n};\nTaskFormFieldTypeHouseholdMember.displayName = 'FieldType: Household Member';"]}