cspace-ui
Version:
CollectionSpace user interface for browsers
179 lines (144 loc) • 6.27 kB
JavaScript
"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");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _extends() { _extends = Object.assign || 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 defaultViewConfigKey = 'view';
const renderLabel = (fieldDescriptor, providedLabelMessage, recordData, 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)(fieldDescriptor, recordData);
}
if ('readOnly' in fieldConfig) {
configuredProps.readOnly = fieldConfig.readOnly;
}
return _react.default.createElement(Label, _extends({}, props, configuredProps), _react.default.createElement(_reactIntl.FormattedMessage, message));
};
const propTypes = {
labelMessage: _propTypes.default.object,
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.
value: _propTypes.default.any,
parentPath: _propTypes.default.array,
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.object,
intl: _reactIntl.intlShape,
recordData: _propTypes.default.instanceOf(_immutable.default.Map),
recordType: _propTypes.default.string,
recordTypeConfig: _propTypes.default.object
};
function Field(props, context) {
const {
config,
intl,
recordData,
recordType
} = context;
const {
labelMessage,
viewType
} = props;
const recordTypeConfig = context.recordTypeConfig || (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 ".concat(recordType, ". The field with path ").concat(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 ".concat(path, " is not present in the field descriptors for the record type ").concat(recordType, ". The field will not be rendered.")) : void 0;
if (!field) {
return null;
}
const fieldConfig = field[_configHelpers.configKey];
const viewConfigKey = viewType === 'search' ? 'searchView' : defaultViewConfigKey;
const viewConfig = fieldConfig[viewConfigKey] || fieldConfig[defaultViewConfigKey];
const BaseComponent = viewConfig.type;
const configuredProps = viewConfig.props || {};
const providedProps = {};
const basePropTypes = BaseComponent.propTypes;
Object.keys(props).forEach(propName => {
if (propName in basePropTypes) {
providedProps[propName] = props[propName];
}
});
const effectiveReadOnly = providedProps.readOnly || configuredProps.readOnly;
const computedProps = {};
if (fieldConfig.repeating && viewType !== 'search') {
computedProps.repeating = fieldConfig.repeating;
}
if ('label' in basePropTypes) {
computedProps.label = renderLabel(field, labelMessage, recordData, {
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];
return childField && renderLabel(childField, childLabelMessage, recordData, {
key: childName,
readOnly: effectiveReadOnly
});
};
}
if ('viewType' in basePropTypes) {
computedProps.viewType = viewType;
}
const effectiveProps = Object.assign({}, computedProps, configuredProps, providedProps, {
readOnly: effectiveReadOnly
});
return _react.default.createElement(BaseComponent, effectiveProps);
}
Field.contextTypes = contextTypes;
Field.propTypes = propTypes;