import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import {get, set, isEmpty, findKey, orderBy, map} from 'lodash'; import {gettext} from 'core/utils'; import {InputArray, MultiTextInput, Input, Toggle, ToggleBox, ContactNumberInput, Label, SelectFieldSearchInput} from './index'; import {validateMinRequiredField, getContactTypeObject, getMinRequiredFieldLabels, getMinRequiredFieldLabel} from '../../../contacts/helpers'; import {IContact, IContactsService, IContactType} from '../../Contacts'; import { Row, RowItem, LineInput, SelectInput, } from 'core/ui/components/Form'; interface IProps { svc: { metadata: { values: { regions: Array; countries: Array; contact_type: Array; contact_job_titles: Array; contact_phone_usage: Array; contact_mobile_usage: Array; } }; contacts: IContactsService; privileges: any; }; contact: IContact; contactType: string; onChange(field: string, value: any, e?: any): void; readOnly: boolean; errors: {[key: string]: string}; } interface IState { jobTitles?: any; stateNames?: any; countries?: any; phoneUsages?: any; mobileUsages?: any; displayOtherStateField?: any; requiredField?: any; touched?: any; organisations?: any; orgValue?: any; contactTypes?: Array; contactType?: IContactType; } export class ProfileDetail extends React.PureComponent { static propTypes: any; static defaultProps: any; constructor(props: IProps) { super(props); const {svc, contact} = props; const {metadata} = svc; let stateNames = [], countries = [], contactTypes = []; if (metadata.values.regions) { stateNames = orderBy(metadata.values.regions, 'name', 'asc'); } if (metadata.values.countries) { countries = orderBy(metadata.values.countries, 'name', 'asc'); } if (metadata.values.contact_type) { contactTypes = orderBy(metadata.values.contact_type, 'name', 'asc'); } this.state = { jobTitles: orderBy(metadata.values.contact_job_titles, 'name', 'asc') || [], stateNames: stateNames, countries: countries, phoneUsages: metadata.values.contact_phone_usage || [], mobileUsages: metadata.values.contact_mobile_usage || [], displayOtherStateField: this.shouldDisplayOtherState(props) || false, requiredField: !validateMinRequiredField(contact) || false, touched: {}, organisations: [], orgValue: (contact && contact.organisation) ? contact.organisation : '', contactTypes: contactTypes, contactType: null, }; this.changeOtherStateField = this.changeOtherStateField.bind(this); this.onBlur = this.onBlur.bind(this); this.isFieldInvalid = this.isFieldInvalid.bind(this); this.getSearchResult = this.getSearchResult.bind(this); this.handleOrgChange = this.handleOrgChange.bind(this); this.onContactTypeChanged = this.onContactTypeChanged.bind(this); } componentDidMount(): void { if (this.props.contact && this.props.contact.contact_type) { this.setState({ contactType: getContactTypeObject( this.state.contactTypes, this.props.contact.contact_type, ), }); } } onBlur(e) { const _touched = this.state.touched; set(_touched, e.target.name, true); this.setState({touched: _touched}); } isFieldInvalid(field) { return this.state.touched[field] && isEmpty(this.props.contact[field]); } changeOtherStateField(e) { this.setState({displayOtherStateField: e.target.checked}); } shouldDisplayOtherState(props) { const {svc, contact} = props; const {metadata} = svc; return !isEmpty(contact.contact_state) && !findKey(metadata.values.regions, (m) => m.qcode === contact.contact_state); } getSearchResult(field, text) { const {svc} = this.props; const {contacts} = svc; if (text) { contacts.queryField(field, text).then((items) => { switch (field) { case 'organisation': this.setState({ organisations: map(items._items, field), orgValue: text, }); } }); } } handleOrgChange(field, value) { this.setState({ orgValue: value, }); this.props.onChange(field, value); } componentWillReceiveProps(nextProps: IProps) { if (nextProps.contact !== this.props.contact) { const displayOtherState = this.shouldDisplayOtherState(nextProps); const newState: IState = { displayOtherStateField: displayOtherState, requiredField: !validateMinRequiredField(nextProps.contact) || false, orgValue: get(nextProps.contact, 'organisation', ''), }; if (nextProps.contact.contact_type !== this.props.contact.contact_type) { newState.contactType = getContactTypeObject( this.state.contactTypes, nextProps.contact.contact_type, ); } this.setState(newState); } } onContactTypeChanged(field: string, value: IContactType) { this.props.onChange( 'contact_type', (value && value.qcode) ? value.qcode : null, ); } render() { const {contact, onChange, readOnly, errors, contactType} = this.props; const contactLabel = contactType === 'person' ? gettext('Role') : gettext('Point of contact'); const isRequired = get(this.state, 'requiredField', false); const MSG_REQUIRED = gettext('This field is required.'); const isAssignable = this.state.contactType && this.state.contactType.assignable; const minFieldMessage = gettext('At least one of [{{list}}] is required.', {list: getMinRequiredFieldLabels()}); const showMinFieldsWarning = !validateMinRequiredField(contact) && !readOnly; return (
{!readOnly && (
{gettext('Please specify \'first name, last name\' or \'organisation\' or both, ' + 'and at least one of [{{list}}] fields.', {list: getMinRequiredFieldLabels()})}
)} {get(this.state, 'contactTypes.length', 0) > 0 && ( )} {contactType === 'organisation' && ( )} {contactType === 'person' && ( this.getSearchResult('organisation', text))} dataList={this.state.organisations} readOnly={readOnly} /> )} {!this.state.displayOtherStateField && ( ) } {this.state.displayOtherStateField && ( )}