import PropTypes from 'prop-types' import { Typography, Badge, Input, InputNumber, Form, Select, DatePicker, Switch } from 'antd' import IdDisplay from './IdDisplay' import TimeDisplay from './TimeDisplay' import dayjs from 'dayjs' import EmailDisplay from './EmailDisplay' import UrlDisplay from './UrlDisplay' import CountryDisplay from './CountryDisplay' import CountrySelect from './CountrySelect' import TagsDisplay from './TagsDisplay' import TagsInput from './TagsInput' import BoolDisplay from './BoolDisplay' import ColorSelector from './ColorSelector' import SecretDisplay from './SecretDisplay' import EyeIcon from '../../Icons/EyeIcon' import EyeSlashIcon from '../../Icons/EyeSlashIcon' import { getPropertyValue } from '../../../database/ObjectModels' import PropertyChanges from './PropertyChanges' import NetGrossDisplay from './NetGrossDisplay' import NetGrossInput from './NetGrossInput' import ObjectList from './ObjectList' import VarianceDisplay from './VarianceDisplay' import OperationDisplay from './OperationDisplay' import MarkdownDisplay from './MarkdownDisplay' import MarkdownInput from './MarkdownInput' import ObjectSelect from './ObjectSelect' import ObjectDisplay from './ObjectDisplay' import ObjectTypeSelect from './ObjectTypeSelect' import ObjectTypeDisplay from './ObjectTypeDisplay' import CodeBlockEditor from './CodeBlockEditor' import StateDisplay from './StateDisplay' import AlertsDisplay from './AlertsDisplay' import FileUpload from './FileUpload' import DataTree from './DataTree' import FileList from './FileList' const { Text } = Typography const MATERIAL_OPTIONS = [ { value: 'PLA', label: 'PLA' }, { value: 'PETG', label: 'PETG' }, { value: 'ABS', label: 'ABS' }, { value: 'ASA', label: 'ASA' }, { value: 'HIPS', label: 'HIPS' }, { value: 'TPU', label: 'TPU' } ] const ObjectProperty = ({ type = 'text', prefix, suffix, value, min, max, difference, step, isEditing = false, formItemProps = {}, required = false, name, label, showLabel = false, masterFilter = {}, language = '', objectData = null, objectType = 'unknown', readOnly = false, disabled = false, empty = false, initial = false, height = 'auto', minimal = false, previewOpen = false, showPreview = true, options = [], showHyperlink, ...rest }) => { if (value && typeof value == 'function' && objectData) { value = value(objectData) } if (objectType && typeof objectType == 'function' && objectData) { objectType = objectType(objectData) } if (disabled && typeof disabled == 'function' && objectData) { disabled = disabled(objectData) } if (empty && typeof empty == 'function' && objectData) { empty = empty(objectData) } if (difference && typeof difference == 'function' && objectData) { difference = difference(objectData) } if (prefix && typeof prefix == 'function' && objectData) { prefix = prefix(objectData) } if (suffix && typeof suffix == 'function' && objectData) { suffix = suffix(objectData) } if (masterFilter && typeof masterFilter == 'function' && objectData) { masterFilter = masterFilter(objectData) } if (!value) { value = getPropertyValue(objectData, name) } // Split the name by "." to handle nested object properties var formItemName = name if (name?.includes('.')) { formItemName = name ? name.split('.') : undefined } var textParams = { style: { whiteSpace: 'nowrap', minWidth: '0' } } if (disabled == true) { textParams = { ...textParams, delete: true, type: 'secondary' } } const renderProperty = () => { if (empty == true) { return n/a } if (!isEditing || (readOnly && !initial)) { switch (type) { case 'netGross': return ( ) case 'secret': if (value != null) { return } else { return ( n/a ) } case 'wsprotocol': switch (value) { case 'ws': return Websocket case 'wss': return Websocket Secure default: return ( n/a ) } case 'priceMode': switch (value) { case 'margin': return Margin % case 'amount': return £ Amount default: return ( n/a ) } case 'bool': { if (value != null) { return } else { return ( n/a ) } } case 'dateTime': { if (value != null) { return } else { return ( n/a ) } } case 'country': { if (value != null) { return } else { return ( n/a ) } } case 'color': { if (value) { return } else { return ( n/a ) } } case 'number': { if (value != null) { if (Array.isArray(value)) { return ( {prefix} {value.length} {suffix} ) } else { return ( {prefix} {typeof value === 'number' ? value.toFixed(2) : value} {suffix} ) } } else { return ( n/a ) } } case 'variance': { if (value != null) { return ( ) } else { return ( n/a ) } } case 'text': if (value != null && value != '') { return ( {prefix} {value} {suffix} ) } else { return ( n/a ) } case 'codeBlock': if (value != null && value != '') { return ( ) } else { return ( n/a ) } case 'markdown': if (value != null && value != '') { return } else { return ( n/a ) } case 'email': if (value != null && value != '') { return } else { return ( n/a ) } case 'url': if (value != null && value != '') { return } else { return ( n/a ) } case 'object': { if (value && value._id) { return } else { return ( n/a ) } } case 'objectType': { if (value) { return } else { return ( n/a ) } } case 'objectList': { return } case 'state': { if (value && value?.type) { return } else { return ( n/a ) } } case 'material': { if (value) { return {value} } else { return ( n/a ) } } case 'id': { if (value) { return ( ) } else { return ( n/a ) } } case 'density': { if (value != null) { return {`${value} g/cm³`} } else { return ( n/a ) } } case 'alerts': { if (value != null && value?.length != 0) { return } else { return ( n/a ) } } case 'tags': { if (value != null || value?.length != 0) { return } else { return ( n/a ) } } case 'operation': { if (value != null) { return } else { return ( n/a ) } } case 'propertyChanges': { return } case 'data': { return } case 'file': { if (value == null || value?.length == 0 || value == undefined) { return ( n/a ) } else { return ( ) } } case 'fileList': { return ( ) } default: { if (value) { return {value} } else { return ( n/a ) } } } } // Editable mode: wrap in Form.Item // Merge required rule if needed let mergedFormItemProps = { ...formItemProps, style: { flexGrow: 1 } } if (required && disabled == false) { let rules if (mergedFormItemProps.rules) { rules = [...mergedFormItemProps.rules] } else { rules = [] } const hasRequiredRule = rules.some((rule) => rule && rule.required) if (!hasRequiredRule) { rules.push({ required: true, message: '' }) } mergedFormItemProps.rules = rules } // Remove name from mergedFormItemProps if present if (mergedFormItemProps.name) { delete mergedFormItemProps.name } // If label is provided, set it on Form.Item if (label && showLabel == true) { mergedFormItemProps.label = label } // Always apply style: { margin: 0 } unless overridden mergedFormItemProps.style = { margin: 0, ...(mergedFormItemProps.style || {}) } switch (type) { case 'netGross': return ( ) case 'secret': return ( visible ? : } /> ) case 'wsprotocol': return ( ) case 'priceMode': return ( ) case 'codeBlock': return ( ) case 'markdown': return ( ) case 'material': return ( ) } } const property = renderProperty() // Render the property directly (remove useDescriptions functionality) return property } ObjectProperty.propTypes = { type: PropTypes.string.isRequired, value: PropTypes.oneOfType([PropTypes.any, PropTypes.func]), isEditing: PropTypes.bool, formItemProps: PropTypes.object, masterFilter: PropTypes.object, required: PropTypes.bool, name: PropTypes.string, language: PropTypes.string, prefix: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), suffix: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), min: PropTypes.number, max: PropTypes.number, step: PropTypes.number, showLabel: PropTypes.bool, objectType: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), readOnly: PropTypes.bool, disabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]), empty: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]), difference: PropTypes.oneOfType([PropTypes.any, PropTypes.func]), objectData: PropTypes.object, height: PropTypes.string, previewOpen: PropTypes.bool, showPreview: PropTypes.bool, showHyperlink: PropTypes.bool, options: PropTypes.array } export default ObjectProperty