Compare commits
No commits in common. "e85eda5bb0009345bfc9c293318ffb4b17ad28dd" and "b23030274560fe9b75c9ecfc5aa7fce7e0c9462a" have entirely different histories.
e85eda5bb0
...
b230302745
@ -625,19 +625,19 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
|||||||
background-color: #141414;
|
background-color: #141414;
|
||||||
border-inline-end: 1px solid rgba(253, 253, 253, 0.12);
|
border-inline-end: 1px solid rgba(253, 253, 253, 0.12);
|
||||||
border-bottom: 1px solid rgba(253, 253, 253, 0.12);
|
border-bottom: 1px solid rgba(253, 253, 253, 0.12);
|
||||||
border-radius: 0 0 6.5px 0;
|
border-radius: 0 0 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-scroll.simplebar-scrolling .simplebar-track.simplebar-vertical {
|
.sidebar-scroll.simplebar-scrolling .simplebar-track.simplebar-vertical {
|
||||||
width: 12px !important;
|
width: 10px !important;
|
||||||
right: -13px;
|
right: -11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-scroll
|
.sidebar-scroll
|
||||||
.simplebar-track.simplebar-vertical
|
.simplebar-track.simplebar-vertical
|
||||||
.simplebar-scrollbar:before {
|
.simplebar-scrollbar:before {
|
||||||
top: 4px;
|
top: 3px;
|
||||||
bottom: 4px;
|
bottom: 3px;
|
||||||
left: 4px;
|
left: 3px;
|
||||||
right: 4px;
|
right: 3px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -186,7 +186,6 @@ const ObjectChildTable = ({
|
|||||||
{...property}
|
{...property}
|
||||||
longId={false}
|
longId={false}
|
||||||
objectData={record}
|
objectData={record}
|
||||||
parentData={objectData}
|
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
useFormItem={false}
|
useFormItem={false}
|
||||||
name={undefined}
|
name={undefined}
|
||||||
|
|||||||
@ -6,11 +6,11 @@ import {
|
|||||||
InputNumber,
|
InputNumber,
|
||||||
Form,
|
Form,
|
||||||
Select,
|
Select,
|
||||||
|
DatePicker,
|
||||||
Switch
|
Switch
|
||||||
} from 'antd'
|
} from 'antd'
|
||||||
import IdDisplay from './IdDisplay'
|
import IdDisplay from './IdDisplay'
|
||||||
import TimeDisplay from './TimeDisplay'
|
import TimeDisplay from './TimeDisplay'
|
||||||
import TimeEdit from './TimeEdit'
|
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import EmailDisplay from './EmailDisplay'
|
import EmailDisplay from './EmailDisplay'
|
||||||
import UrlDisplay from './UrlDisplay'
|
import UrlDisplay from './UrlDisplay'
|
||||||
@ -51,10 +51,6 @@ import { round } from '../utils/Utils'
|
|||||||
|
|
||||||
const { Text } = Typography
|
const { Text } = Typography
|
||||||
|
|
||||||
const timeEditFormItemProps = {
|
|
||||||
getValueProps: (v) => ({ value: v ? dayjs(v) : null })
|
|
||||||
}
|
|
||||||
|
|
||||||
const ObjectProperty = ({
|
const ObjectProperty = ({
|
||||||
type = 'text',
|
type = 'text',
|
||||||
prefix,
|
prefix,
|
||||||
@ -74,7 +70,6 @@ const ObjectProperty = ({
|
|||||||
masterFilter = {},
|
masterFilter = {},
|
||||||
language = '',
|
language = '',
|
||||||
objectData = null,
|
objectData = null,
|
||||||
parentData = null,
|
|
||||||
objectType = 'unknown',
|
objectType = 'unknown',
|
||||||
readOnly = false,
|
readOnly = false,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
@ -101,51 +96,50 @@ const ObjectProperty = ({
|
|||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
if (value && typeof value == 'function' && objectData) {
|
if (value && typeof value == 'function' && objectData) {
|
||||||
value = value(objectData, parentData)
|
value = value(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max && typeof max == 'function' && objectData) {
|
if (max && typeof max == 'function' && objectData) {
|
||||||
max = max(objectData, parentData)
|
max = max(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min && typeof min == 'function' && objectData) {
|
if (min && typeof min == 'function' && objectData) {
|
||||||
min = min(objectData, parentData)
|
min = min(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objectType && typeof objectType == 'function' && objectData) {
|
if (objectType && typeof objectType == 'function' && objectData) {
|
||||||
objectType = objectType(objectData, parentData)
|
objectType = objectType(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disabled && typeof disabled == 'function' && objectData) {
|
if (disabled && typeof disabled == 'function' && objectData) {
|
||||||
disabled = disabled(objectData, parentData)
|
disabled = disabled(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty && typeof empty == 'function' && objectData) {
|
if (empty && typeof empty == 'function' && objectData) {
|
||||||
empty = empty(objectData, parentData)
|
empty = empty(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (difference && typeof difference == 'function' && objectData) {
|
if (difference && typeof difference == 'function' && objectData) {
|
||||||
difference = difference(objectData, parentData)
|
difference = difference(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefix && typeof prefix == 'function' && objectData) {
|
if (prefix && typeof prefix == 'function' && objectData) {
|
||||||
prefix = prefix(objectData, parentData)
|
prefix = prefix(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (suffix && typeof suffix == 'function' && objectData) {
|
if (suffix && typeof suffix == 'function' && objectData) {
|
||||||
suffix = suffix(objectData, parentData)
|
suffix = suffix(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (masterFilter && typeof masterFilter == 'function' && objectData) {
|
if (masterFilter && typeof masterFilter == 'function' && objectData) {
|
||||||
masterFilter = masterFilter(objectData, parentData)
|
masterFilter = masterFilter(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options && typeof options == 'function' && objectData) {
|
if (options && typeof options == 'function' && objectData) {
|
||||||
options = options(objectData, parentData)
|
options = options(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readOnly && typeof readOnly == 'function' && objectData) {
|
if (readOnly && typeof readOnly == 'function' && objectData) {
|
||||||
readOnly = readOnly(objectData, parentData)
|
readOnly = readOnly(objectData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
@ -714,7 +708,14 @@ const ObjectProperty = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case 'dateTime':
|
case 'dateTime':
|
||||||
return <TimeEdit {...inputProps} />
|
return (
|
||||||
|
<DatePicker
|
||||||
|
showTime
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
{...inputProps}
|
||||||
|
{...(useFormItem ? {} : { value: value ? dayjs(value) : null })}
|
||||||
|
/>
|
||||||
|
)
|
||||||
case 'country':
|
case 'country':
|
||||||
return <CountrySelect {...inputProps} />
|
return <CountrySelect {...inputProps} />
|
||||||
case 'color':
|
case 'color':
|
||||||
@ -853,7 +854,9 @@ const ObjectProperty = ({
|
|||||||
{...(type === 'color'
|
{...(type === 'color'
|
||||||
? { valuePropName: 'value', getValueFromEvent: (v) => v }
|
? { valuePropName: 'value', getValueFromEvent: (v) => v }
|
||||||
: {})}
|
: {})}
|
||||||
{...(type === 'dateTime' ? timeEditFormItemProps : {})}
|
{...(type === 'dateTime'
|
||||||
|
? { getValueProps: (v) => ({ value: v ? dayjs(v) : null }) }
|
||||||
|
: {})}
|
||||||
>
|
>
|
||||||
{renderInput()}
|
{renderInput()}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -1,180 +0,0 @@
|
|||||||
import { useState, useRef } from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import { DatePicker, Input } from 'antd'
|
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import FunctionIcon from '../../Icons/FunctionIcon'
|
|
||||||
|
|
||||||
const OPERATOR_KEYS = ['+', '-']
|
|
||||||
|
|
||||||
const TIME_UNITS = {
|
|
||||||
s: 'second',
|
|
||||||
m: 'minute',
|
|
||||||
h: 'hour',
|
|
||||||
d: 'day',
|
|
||||||
w: 'week',
|
|
||||||
M: 'month',
|
|
||||||
y: 'year'
|
|
||||||
}
|
|
||||||
|
|
||||||
const TERM_REGEX = /([+-])(\d+(?:\.\d+)?)([smhdwMy])/g
|
|
||||||
const RELATIVE_TERM_START = /[+-]\d+(?:\.\d+)?[smhdwMy]/
|
|
||||||
const DATE_EXPR_FORMAT = 'YYYY-MM-DD HH:mm:ss'
|
|
||||||
|
|
||||||
function formatExprBase(date) {
|
|
||||||
if (date == null || !dayjs(date).isValid()) return ''
|
|
||||||
return dayjs(date).format(DATE_EXPR_FORMAT)
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyTimeExpr(fallbackBase, expr) {
|
|
||||||
const trimmed = String(expr).trim()
|
|
||||||
if (!trimmed) return null
|
|
||||||
|
|
||||||
const termStart = trimmed.search(RELATIVE_TERM_START)
|
|
||||||
if (termStart === -1) return null
|
|
||||||
|
|
||||||
let base
|
|
||||||
let termsPart
|
|
||||||
|
|
||||||
if (termStart === 0) {
|
|
||||||
base =
|
|
||||||
fallbackBase && dayjs(fallbackBase).isValid()
|
|
||||||
? dayjs(fallbackBase)
|
|
||||||
: dayjs()
|
|
||||||
termsPart = trimmed
|
|
||||||
} else {
|
|
||||||
const baseStr = trimmed.slice(0, termStart).trim()
|
|
||||||
const parsed = dayjs(baseStr)
|
|
||||||
base = parsed.isValid()
|
|
||||||
? parsed
|
|
||||||
: fallbackBase && dayjs(fallbackBase).isValid()
|
|
||||||
? dayjs(fallbackBase)
|
|
||||||
: dayjs()
|
|
||||||
termsPart = trimmed.slice(termStart)
|
|
||||||
}
|
|
||||||
|
|
||||||
const termsStr = termsPart.replace(/\s/g, '')
|
|
||||||
const terms = [...termsStr.matchAll(TERM_REGEX)]
|
|
||||||
if (!terms.length) return null
|
|
||||||
|
|
||||||
const consumed = terms.map((t) => t[0]).join('')
|
|
||||||
if (consumed !== termsStr) return null
|
|
||||||
|
|
||||||
let result = base
|
|
||||||
for (const [, sign, amount, unit] of terms) {
|
|
||||||
const unitKey = TIME_UNITS[unit]
|
|
||||||
if (!unitKey) return null
|
|
||||||
const delta = sign === '+' ? parseFloat(amount) : -parseFloat(amount)
|
|
||||||
result = result.add(delta, unitKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
const TimeEdit = ({
|
|
||||||
value,
|
|
||||||
onChange,
|
|
||||||
onBlur,
|
|
||||||
disabled,
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const [isExprMode, setIsExprMode] = useState(false)
|
|
||||||
const [exprValue, setExprValue] = useState('')
|
|
||||||
const inputRef = useRef(null)
|
|
||||||
|
|
||||||
const dayjsValue =
|
|
||||||
value == null ? null : dayjs.isDayjs(value) ? value : dayjs(value)
|
|
||||||
const pickerValue =
|
|
||||||
dayjsValue && dayjsValue.isValid() ? dayjsValue : null
|
|
||||||
|
|
||||||
const switchToExprMode = (initialValue) => {
|
|
||||||
setIsExprMode(true)
|
|
||||||
setExprValue(initialValue)
|
|
||||||
setTimeout(() => {
|
|
||||||
const input = inputRef.current?.getElementsByTagName('input')[0]
|
|
||||||
input?.focus()
|
|
||||||
}, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
const exitExprMode = (result) => {
|
|
||||||
setIsExprMode(false)
|
|
||||||
setExprValue('')
|
|
||||||
if (result != null && result.isValid()) {
|
|
||||||
onChange?.(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const commitExpr = () => {
|
|
||||||
const expr = exprValue.trim()
|
|
||||||
if (expr && expr.match(/[+-]/) && expr.match(/[smhdwMy]/)) {
|
|
||||||
const result = applyTimeExpr(pickerValue, expr)
|
|
||||||
if (result != null) {
|
|
||||||
exitExprMode(result)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exitExprMode(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleDatePickerKeyDown = (e) => {
|
|
||||||
if (OPERATOR_KEYS.includes(e.key)) {
|
|
||||||
e.preventDefault()
|
|
||||||
e.stopPropagation()
|
|
||||||
switchToExprMode(formatExprBase(pickerValue) + e.key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleInputKeyDown = (e) => {
|
|
||||||
if (e.key === 'Enter' || e.key === '=') {
|
|
||||||
e.preventDefault()
|
|
||||||
const result = applyTimeExpr(pickerValue, exprValue)
|
|
||||||
if (result != null) {
|
|
||||||
exitExprMode(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleInputBlur = (e) => {
|
|
||||||
commitExpr()
|
|
||||||
onBlur?.(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isExprMode) {
|
|
||||||
return (
|
|
||||||
<div className='input-number-cal' ref={inputRef}>
|
|
||||||
<Input
|
|
||||||
value={exprValue}
|
|
||||||
onChange={(e) => setExprValue(e.target.value)}
|
|
||||||
onKeyDown={handleInputKeyDown}
|
|
||||||
onBlur={handleInputBlur}
|
|
||||||
disabled={disabled}
|
|
||||||
placeholder='+1d, -2m, +1h'
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
/>
|
|
||||||
<div className='input-number-cal-icon'>
|
|
||||||
<FunctionIcon style={{ fontSize: 24 }} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DatePicker
|
|
||||||
showTime
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
value={pickerValue}
|
|
||||||
onChange={onChange}
|
|
||||||
onKeyDown={handleDatePickerKeyDown}
|
|
||||||
disabled={disabled}
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeEdit.propTypes = {
|
|
||||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
|
||||||
onChange: PropTypes.func,
|
|
||||||
onBlur: PropTypes.func,
|
|
||||||
disabled: PropTypes.bool
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TimeEdit
|
|
||||||
@ -402,13 +402,7 @@ export const Invoice = {
|
|||||||
objectType: 'orderItem',
|
objectType: 'orderItem',
|
||||||
required: true,
|
required: true,
|
||||||
columnWidth: 300,
|
columnWidth: 300,
|
||||||
showHyperlink: true,
|
showHyperlink: true
|
||||||
masterFilter: (objectData, parentData) => {
|
|
||||||
return {
|
|
||||||
orderType: parentData?.orderType,
|
|
||||||
order: parentData?.order?._id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'invoiceQuantity',
|
name: 'invoiceQuantity',
|
||||||
@ -522,13 +516,7 @@ export const Invoice = {
|
|||||||
objectType: 'shipment',
|
objectType: 'shipment',
|
||||||
required: true,
|
required: true,
|
||||||
columnWidth: 300,
|
columnWidth: 300,
|
||||||
showHyperlink: true,
|
showHyperlink: true
|
||||||
masterFilter: (objectData, parentData) => {
|
|
||||||
return {
|
|
||||||
orderType: parentData?.orderType,
|
|
||||||
order: parentData?.order?._id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'invoiceAmount',
|
name: 'invoiceAmount',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user