UNPKG

cspace-ui

Version:
199 lines (193 loc) 7.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Field; var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactIntl = require("react-intl"); var _immutable = _interopRequireDefault(require("immutable")); var _get = _interopRequireDefault(require("lodash/get")); var _warning = _interopRequireDefault(require("warning")); var _cspaceInput = require("cspace-input"); var _configHelpers = require("../../helpers/configHelpers"); var _configContextInputs = require("../../helpers/configContextInputs"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } const { getPath, pathPropType } = _cspaceInput.helpers.pathHelpers; const { Label } = _cspaceInput.components; const renderLabel = (fieldDescriptor, providedLabelMessage, computeContext, props) => { const fieldConfig = fieldDescriptor[_configHelpers.configKey]; const message = providedLabelMessage || (0, _get.default)(fieldConfig, ['messages', 'name']); if (!message) { return null; } const configuredProps = {}; if ('required' in fieldConfig) { configuredProps.required = (0, _configHelpers.isFieldRequired)(computeContext); } const viewReadOnly = (0, _configHelpers.isFieldViewReadOnly)(computeContext); if (typeof viewReadOnly !== 'undefined') { configuredProps.readOnly = viewReadOnly; } return /*#__PURE__*/_react.default.createElement(Label, _extends({}, props, configuredProps), /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, message)); }; const propTypes = { labelMessage: _propTypes.default.shape({ id: _propTypes.default.string, defaultMessage: _propTypes.default.string }), viewType: _propTypes.default.string, // Code in this component doesn't use these props, but the propTypes need to exist, because // users of this component may check for them to determine if those props should be passed. // We want to receive all the props that our base components may need, and then we'll handle // distributing them to the base components that accept them. /* eslint-disable react/no-unused-prop-types */ name: _propTypes.default.string, // The value prop will be validated by the base component, so allow anything here. // eslint-disable-next-line react/forbid-prop-types value: _propTypes.default.any, parentPath: _propTypes.default.arrayOf(_propTypes.default.string), subpath: pathPropType, tabular: _propTypes.default.bool, label: _propTypes.default.node, readOnly: _propTypes.default.bool, onAddInstance: _propTypes.default.func, onCommit: _propTypes.default.func, onMoveInstance: _propTypes.default.func, onRemoveInstance: _propTypes.default.func, onSortInstances: _propTypes.default.func /* eslint-enable react/no-unused-prop-types */ }; const contextTypes = { config: _propTypes.default.shape({ recordTypes: _propTypes.default.object }), formName: _propTypes.default.string, intl: _reactIntl.intlShape, recordData: _propTypes.default.instanceOf(_immutable.default.Map), recordType: _propTypes.default.string, recordTypeConfig: _propTypes.default.shape({ fields: _propTypes.default.object }), roleNames: _propTypes.default.instanceOf(_immutable.default.List), subrecordData: _propTypes.default.instanceOf(_immutable.default.Map) }; function Field(props, context) { const { config, formName, intl, recordData, recordType, roleNames, subrecordData, recordTypeConfig: contextRecordTypeConfig } = context; const { labelMessage, viewType } = props; const recordTypeConfig = contextRecordTypeConfig || (0, _get.default)(config, ['recordTypes', recordType]); const fullPath = getPath(props); // Filter out numeric parts of the path, since they indicate repeating instances that won't be // present in the field descriptor. const path = (0, _configHelpers.dataPathToFieldDescriptorPath)(fullPath); const fields = (0, _get.default)(recordTypeConfig, 'fields'); process.env.NODE_ENV !== "production" ? (0, _warning.default)(fields, `No field descriptor found for the record type ${recordType}. The field with path ${path} will not be rendered.`) : void 0; if (!fields) { return null; } const field = (0, _get.default)(fields, path); process.env.NODE_ENV !== "production" ? (0, _warning.default)(field, `The path ${path} is not present in the field descriptors for the record type ${recordType}. The field will not be rendered.`) : void 0; if (!field) { return null; } const fieldConfig = field[_configHelpers.configKey]; const isSearch = viewType === 'search'; const viewConfig = isSearch ? fieldConfig.searchView || fieldConfig.view : fieldConfig.view; let BaseComponent = viewConfig.type; if (isSearch && !fieldConfig.searchView && BaseComponent === _configContextInputs.StructuredDateInput) { // If a search view was not explicitly configured, and the view is a StructuredDateInput, // automatically make the search view a DateInput. BaseComponent = _configContextInputs.DateInput; } const configuredProps = viewConfig.props || {}; const providedProps = {}; // FIXME: Do this without looking at the base component propTypes, so that propTypes can be // removed in production builds. // eslint-disable-next-line react/forbid-foreign-prop-types const basePropTypes = BaseComponent.propTypes; Object.keys(props).forEach(propName => { if (propName in basePropTypes) { // eslint-disable-next-line react/destructuring-assignment providedProps[propName] = props[propName]; } }); const computeContext = { isSearch, path, recordData, subrecordData, fieldDescriptor: field, recordType, form: formName, roleNames }; const effectiveReadOnly = providedProps.readOnly || (0, _configHelpers.isFieldViewReadOnly)(computeContext); const computedProps = {}; if (fieldConfig.repeating && viewType !== 'search') { computedProps.repeating = fieldConfig.repeating; } if ('label' in basePropTypes) { computedProps.label = renderLabel(field, labelMessage, computeContext, { readOnly: effectiveReadOnly }); } if ('formatValue' in basePropTypes) { const valueMessage = (0, _get.default)(fieldConfig, ['messages', 'value']); if (valueMessage) { computedProps.formatValue = value => intl.formatMessage(valueMessage, { value }); } } if ('renderChildInputLabel' in basePropTypes) { computedProps.renderChildInputLabel = childInput => { const childName = childInput.props.name; const childLabelMessage = childInput.props.labelMessage; const childField = field[childName]; const childComputeContext = { path: [...path, childName], recordData, subrecordData, fieldDescriptor: childField, recordType, form: formName, roleNames }; return childField && renderLabel(childField, childLabelMessage, childComputeContext, { key: childName, readOnly: effectiveReadOnly }); }; } if ('viewType' in basePropTypes) { computedProps.viewType = viewType; } const effectiveProps = { ...computedProps, ...configuredProps, ...providedProps, readOnly: effectiveReadOnly }; return /*#__PURE__*/_react.default.createElement(BaseComponent, effectiveProps); } Field.contextTypes = contextTypes; Field.propTypes = propTypes; Field.toJSON = () => 'Field';