diff --git a/src/components/Dashboard/common/ObjectProperty.jsx b/src/components/Dashboard/common/ObjectProperty.jsx
index 3a6ba35..33a15bf 100644
--- a/src/components/Dashboard/common/ObjectProperty.jsx
+++ b/src/components/Dashboard/common/ObjectProperty.jsx
@@ -27,6 +27,8 @@ import { getPropertyValue } from '../../../database/ObjectModels'
import PropertyChanges from './PropertyChanges'
import NetGrossDisplay from './NetGrossDisplay'
import NetGrossInput from './NetGrossInput'
+import MinMaxDisplay from './MinMaxDisplay'
+import MinMaxInput from './MinMaxInput'
import InputNumberCal from './InputNumberCal'
import ObjectList from './ObjectList'
import VarianceDisplay from './VarianceDisplay'
@@ -47,10 +49,35 @@ import FileList from './FileList'
import ObjectChildTable from './ObjectChildTable'
import MiscId from './MiscId'
import AddressDisplay from './AddressDisplay'
+import ArrayDisplay from './ArrayDisplay'
+import ArrayInput from './ArrayInput'
import { round } from '../utils/Utils'
const { Text } = Typography
+const getTextValue = (value) => {
+ if (value == null || typeof value === 'string' || typeof value === 'number') {
+ return value
+ }
+
+ if (typeof value === 'object') {
+ if (typeof value._id === 'string') {
+ return value._id
+ }
+ if (typeof value._id?._id === 'string') {
+ return value._id._id
+ }
+
+ try {
+ return JSON.stringify(value)
+ } catch {
+ return String(value)
+ }
+ }
+
+ return String(value)
+}
+
const timeEditFormItemProps = {
getValueProps: (v) => ({ value: v ? dayjs(v) : null })
}
@@ -97,7 +124,10 @@ const ObjectProperty = ({
loading = false,
rollups = [],
showCard = true,
+ showDownload = true,
+ columns = [],
style = {},
+ hiddenPropertyWidth = '100px',
...rest
}) => {
if (value && typeof value == 'function' && objectData) {
@@ -152,7 +182,11 @@ const ObjectProperty = ({
type = type(objectData, parentData)
}
- if (!value) {
+ if (columns && typeof columns == 'function' && objectData) {
+ columns = columns(objectData, parentData)
+ }
+
+ if (value == null) {
value = getPropertyValue(objectData, name)
}
@@ -183,6 +217,15 @@ const ObjectProperty = ({
return (
)
+ case 'minMax':
+ return (
+
+ )
case 'secret':
if (value != null) {
return
@@ -313,6 +356,9 @@ const ObjectProperty = ({
)
}
}
+ case 'numberList':
+ case 'stringList':
+ return
case 'variance': {
if (value != null) {
return (
@@ -331,7 +377,7 @@ const ObjectProperty = ({
return (
{prefix}
- {value}
+ {getTextValue(value)}
{suffix}
)
@@ -432,8 +478,10 @@ const ObjectProperty = ({
loading={loading}
rollups={rollups}
size={size}
+ hiddenPropertyWidth={hiddenPropertyWidth}
minimal={minimal}
label={label}
+ columns={columns}
canAddRemove={canAddRemove}
/>
)
@@ -571,6 +619,7 @@ const ObjectProperty = ({
defaultPreviewOpen={previewOpen}
showPreview={showPreview}
showInfo={showHyperlink}
+ showDownload={showDownload}
/>
)
}
@@ -588,8 +637,8 @@ const ObjectProperty = ({
)
}
default: {
- if (value) {
- return {value}
+ if (value != null && value !== '') {
+ return {getTextValue(value)}
} else {
return (
@@ -620,6 +669,59 @@ const ObjectProperty = ({
}
mergedFormItemProps.rules = rules
}
+ if (type === 'minMax' && disabled == false) {
+ const rules = [...(mergedFormItemProps.rules || [])]
+ rules.push({
+ validator: (_, range) => {
+ if (range == null) return Promise.resolve()
+ if (typeof range !== 'object' || Array.isArray(range)) {
+ return Promise.reject(new Error('Value must be a min/max range'))
+ }
+
+ const values = [range.min, range.max].filter((item) => item != null)
+ const valid = values.every(
+ (item) =>
+ typeof item === 'number' &&
+ Number.isFinite(item) &&
+ (min == null || item >= min) &&
+ (max == null || item <= max)
+ )
+
+ return valid
+ ? Promise.resolve()
+ : Promise.reject(new Error('Enter valid min and max values'))
+ }
+ })
+ mergedFormItemProps.rules = rules
+ }
+ if ((type === 'numberList' || type === 'stringList') && disabled == false) {
+ const rules = [...(mergedFormItemProps.rules || [])]
+ rules.push({
+ validator: (_, items) => {
+ if (items == null) return Promise.resolve()
+ if (!Array.isArray(items)) {
+ return Promise.reject(new Error('Value must be a list'))
+ }
+
+ const valid = items.every((item) => {
+ if (type === 'numberList') {
+ return (
+ typeof item === 'number' &&
+ Number.isFinite(item) &&
+ (min == null || item >= min) &&
+ (max == null || item <= max)
+ )
+ }
+ return typeof item === 'string' && item.trim().length > 0
+ })
+
+ return valid
+ ? Promise.resolve()
+ : Promise.reject(new Error('Complete or remove empty list items'))
+ }
+ })
+ mergedFormItemProps.rules = rules
+ }
// Remove name from mergedFormItemProps if present
if (mergedFormItemProps.name) {
delete mergedFormItemProps.name
@@ -657,6 +759,17 @@ const ObjectProperty = ({
{...inputProps}
/>
)
+ case 'minMax':
+ return (
+
+ )
case 'secret':
return (
)
+ case 'numberList':
+ return (
+
+ )
+ case 'stringList':
+ return (
+
+ )
case 'text':
return
case 'codeBlock':
@@ -831,9 +964,11 @@ const ObjectProperty = ({