Editor Options Builder

This commit is contained in:
Sedat Öztürk 2026-05-31 21:16:41 +03:00
parent e1c808310d
commit 5806ff5f9f
5 changed files with 131 additions and 84 deletions

View file

@ -24,7 +24,6 @@ const baseInputClass =
const boolOptions = [ const boolOptions = [
{ key: 'showClearButton', label: 'showClearButton' }, { key: 'showClearButton', label: 'showClearButton' },
{ key: 'readOnly', label: 'readOnly' }, { key: 'readOnly', label: 'readOnly' },
{ key: 'disabled', label: 'disabled' },
{ key: 'searchEnabled', label: 'searchEnabled' }, { key: 'searchEnabled', label: 'searchEnabled' },
{ key: 'acceptCustomValue', label: 'acceptCustomValue' }, { key: 'acceptCustomValue', label: 'acceptCustomValue' },
{ key: 'showSpinButtons', label: 'showSpinButtons' }, { key: 'showSpinButtons', label: 'showSpinButtons' },

View file

@ -74,6 +74,11 @@ const FormDevExpress = (props: {
try { try {
const editor = refForm.current?.instance().getEditor(item.dataField!) const editor = refForm.current?.instance().getEditor(item.dataField!)
if (editor && mode !== 'view') { if (editor && mode !== 'view') {
if (item.editorOptions?.disabled === true) {
editor.option('disabled', true)
return
}
// Parent fieldlerden en az biri boşsa disabled olmalı // Parent fieldlerden en az biri boşsa disabled olmalı
const shouldDisable = parentFields.some((parentField: string) => { const shouldDisable = parentFields.some((parentField: string) => {
return !formDataRef.current || !formDataRef.current[parentField] return !formDataRef.current || !formDataRef.current[parentField]
@ -244,8 +249,7 @@ const FormDevExpress = (props: {
key={'formItem-' + i} key={'formItem-' + i}
{...formItem} {...formItem}
editorOptions={{ editorOptions={{
...formItem.editorOptions, ...(mode === 'view' ? {} : { autoFocus: i === 1 }),
...(mode === 'view' ? { readOnly: true } : { autoFocus: i === 1 }),
...(formItem.editorType === 'dxDateBox' ...(formItem.editorType === 'dxDateBox'
? { ? {
useMaskBehavior: true, useMaskBehavior: true,
@ -256,6 +260,8 @@ const FormDevExpress = (props: {
...(formItem.colData?.placeHolder ...(formItem.colData?.placeHolder
? { placeholder: translate('::' + formItem.colData.placeHolder) } ? { placeholder: translate('::' + formItem.colData.placeHolder) }
: {}), : {}),
...formItem.editorOptions,
...(mode === 'view' ? { readOnly: true } : {}),
buttons: (formItem.editorOptions?.buttons || []).map((btn: any) => { buttons: (formItem.editorOptions?.buttons || []).map((btn: any) => {
if (btn?.options?.onClick && typeof btn.options.onClick === 'string') { if (btn?.options?.onClick && typeof btn.options.onClick === 'string') {
const origClick = eval(`(${btn.options.onClick})`) const origClick = eval(`(${btn.options.onClick})`)

View file

@ -224,12 +224,24 @@ const useGridData = (props: {
return a.order >= b.order ? 1 : -1 return a.order >= b.order ? 1 : -1
}) })
.map((i: EditingFormItemDto) => { .map((i: EditingFormItemDto) => {
let editorOptions = {} let editorOptions: Record<string, any> = {}
let parsedEditorOptions: Record<string, any> = {}
const colData = gridDto.columnFormats.find((x) => x.fieldName === i.dataField) const colData = gridDto.columnFormats.find((x) => x.fieldName === i.dataField)
try { try {
editorOptions = i.editorOptions && JSON.parse(i.editorOptions) parsedEditorOptions = i.editorOptions ? JSON.parse(i.editorOptions) : {}
} catch {} } catch {}
const lookupEditorOptions = colData?.lookupDto?.dataSourceType
? {
dataSource: getLookupDataSource(colData?.editorOptions, colData, formData),
valueExpr: colData?.lookupDto?.valueExpr?.toLowerCase(),
displayExpr: colData?.lookupDto?.displayExpr?.toLowerCase(),
}
: {}
editorOptions = {
...lookupEditorOptions,
...parsedEditorOptions,
}
const item: SimpleItemWithColData = { const item: SimpleItemWithColData = {
canRead: canRead:
gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canRead ?? gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canRead ??
@ -260,16 +272,7 @@ const useGridData = (props: {
: i.editorType2, : i.editorType2,
colSpan: i.colSpan, colSpan: i.colSpan,
isRequired: i.isRequired, isRequired: i.isRequired,
editorOptions: { editorOptions,
...editorOptions,
...(colData?.lookupDto?.dataSourceType
? {
dataSource: getLookupDataSource(colData?.editorOptions, colData, formData),
valueExpr: colData?.lookupDto?.valueExpr?.toLowerCase(),
displayExpr: colData?.lookupDto?.displayExpr?.toLowerCase(),
}
: {}),
},
colData, colData,
tagBoxOptions: i.tagBoxOptions, tagBoxOptions: i.tagBoxOptions,
gridBoxOptions: i.gridBoxOptions, gridBoxOptions: i.gridBoxOptions,
@ -315,14 +318,21 @@ const useGridData = (props: {
items: (groupItem.items as SimpleItemWithColData[])?.map((item) => { items: (groupItem.items as SimpleItemWithColData[])?.map((item) => {
const colData = gridDto.columnFormats.find((x) => x.fieldName === item.dataField) const colData = gridDto.columnFormats.find((x) => x.fieldName === item.dataField)
if (colData?.lookupDto?.dataSourceType) { if (colData?.lookupDto?.dataSourceType) {
const currentDataSource = item.editorOptions?.dataSource
const keepCustomDataSource =
currentDataSource !== undefined && typeof currentDataSource?.load !== 'function'
return { return {
...item, ...item,
editorOptions: { editorOptions: {
...item.editorOptions, ...item.editorOptions,
// formData null bile olsa getLookupDataSource çağrılmalı (null parametrelerle API çağrısı yapılacak) // formData null bile olsa getLookupDataSource çağrılmalı (null parametrelerle API çağrısı yapılacak)
dataSource: getLookupDataSource(colData?.editorOptions, colData, formData || null), dataSource: keepCustomDataSource
valueExpr: colData?.lookupDto?.valueExpr?.toLowerCase(), ? currentDataSource
displayExpr: colData?.lookupDto?.displayExpr?.toLowerCase(), : getLookupDataSource(colData?.editorOptions, colData, formData || null),
valueExpr: item.editorOptions?.valueExpr ?? colData?.lookupDto?.valueExpr?.toLowerCase(),
displayExpr:
item.editorOptions?.displayExpr ?? colData?.lookupDto?.displayExpr?.toLowerCase(),
}, },
} }
} }

View file

@ -577,14 +577,21 @@ const Grid = (props: GridProps) => {
const columnFormat = gridDto.columnFormats.find((column) => column.fieldName === fieldName) const columnFormat = gridDto.columnFormats.find((column) => column.fieldName === fieldName)
const isNewRow = Boolean((editor as any).row?.isNewRow) || mode === 'new' const isNewRow = Boolean((editor as any).row?.isNewRow) || mode === 'new'
const hasReadOnlyEditorOption = editor.editorOptions?.readOnly === true
const hasDisabledEditorOption = editor.editorOptions?.disabled === true
if ( if (
(isNewRow && columnFormat?.allowAdding === false) || (isNewRow && columnFormat?.allowAdding === false) ||
(!isNewRow && columnFormat?.allowEditing === false) (!isNewRow && columnFormat?.allowEditing === false)
) { ) {
editor.editorOptions.readOnly = true editor.editorOptions.readOnly = true
} else if (isNewRow && columnFormat?.allowAdding === true) { } else if (isNewRow && columnFormat?.allowAdding === true) {
editor.editorOptions.readOnly = false if (!hasReadOnlyEditorOption) {
editor.editorOptions.disabled = false editor.editorOptions.readOnly = false
}
if (!hasDisabledEditorOption) {
editor.editorOptions.disabled = false
}
} }
// Cascade mantığı // Cascade mantığı
@ -624,7 +631,19 @@ const Grid = (props: GridProps) => {
(pf: string) => !rowData[pf], (pf: string) => !rowData[pf],
) )
try { try {
formInstance.getEditor(childFieldName)?.option('disabled', shouldDisable) const childFormItem = gridDto.gridOptions.editingFormDto
.flatMap((group) => group.items || [])
.find((i) => i.dataField === childFieldName)
const childEditorOptions = childFormItem?.editorOptions
? JSON.parse(childFormItem.editorOptions)
: {}
const childEditor = formInstance.getEditor(childFieldName)
if (childEditorOptions?.disabled === true) {
childEditor?.option('disabled', true)
} else {
childEditor?.option('disabled', shouldDisable)
}
} catch {} } catch {}
} }
}) })
@ -960,17 +979,10 @@ const Grid = (props: GridProps) => {
const mapFormItem = useCallback( const mapFormItem = useCallback(
(i: EditingFormItemDto) => { (i: EditingFormItemDto) => {
let editorOptions: EditorOptionsWithButtons = {} let editorOptions: EditorOptionsWithButtons = {}
let parsedEditorOptions: EditorOptionsWithButtons = {}
const forcedEditorOptions: EditorOptionsWithButtons = {}
try { try {
editorOptions = i.editorOptions && JSON.parse(i.editorOptions) parsedEditorOptions = i.editorOptions ? JSON.parse(i.editorOptions) : {}
if (editorOptions?.buttons) {
editorOptions.buttons = (editorOptions?.buttons || []).map((btn: any) => {
if (btn?.options?.onClick && typeof btn.options.onClick === 'string') {
btn.options.onClick = eval(`(${btn.options.onClick})`)
}
return btn
})
}
const rawFilter = searchParams?.get('filter') const rawFilter = searchParams?.get('filter')
if (rawFilter) { if (rawFilter) {
@ -983,10 +995,7 @@ const Grid = (props: GridProps) => {
const existsInExtra = extraFilters.some((f) => f.fieldName === i.dataField && !!f.value) const existsInExtra = extraFilters.some((f) => f.fieldName === i.dataField && !!f.value)
if (!existsInExtra) { if (!existsInExtra) {
editorOptions = { forcedEditorOptions.readOnly = true
...editorOptions,
readOnly: true,
}
} }
} }
} }
@ -995,36 +1004,29 @@ const Grid = (props: GridProps) => {
const fieldName = i.dataField.split(':')[0] const fieldName = i.dataField.split(':')[0]
const listFormField = gridDto?.columnFormats.find((x: any) => x.fieldName === fieldName) const listFormField = gridDto?.columnFormats.find((x: any) => x.fieldName === fieldName)
const defaultEditorOptions: EditorOptionsWithButtons = {}
if (listFormField?.sourceDbType === DbTypeEnum.Date) { if (listFormField?.sourceDbType === DbTypeEnum.Date) {
editorOptions = { Object.assign(defaultEditorOptions, {
...{
type: 'date', type: 'date',
dateSerializationFormat: 'yyyy-MM-dd', dateSerializationFormat: 'yyyy-MM-dd',
displayFormat: 'shortDate', displayFormat: 'shortDate',
}, })
...editorOptions,
}
} else if ( } else if (
listFormField?.sourceDbType === DbTypeEnum.DateTime || listFormField?.sourceDbType === DbTypeEnum.DateTime ||
listFormField?.sourceDbType === DbTypeEnum.DateTime2 || listFormField?.sourceDbType === DbTypeEnum.DateTime2 ||
listFormField?.sourceDbType === DbTypeEnum.DateTimeOffset listFormField?.sourceDbType === DbTypeEnum.DateTimeOffset
) { ) {
editorOptions = { Object.assign(defaultEditorOptions, {
...{
type: 'datetime', type: 'datetime',
dateSerializationFormat: 'yyyy-MM-ddTHH:mm:ss', dateSerializationFormat: 'yyyy-MM-ddTHH:mm:ss',
displayFormat: 'shortDateShortTime', displayFormat: 'shortDateShortTime',
}, })
...editorOptions,
}
} }
// Her item'a placeholder olarak captionName ekle // Her item'a placeholder olarak captionName ekle
if (listFormField?.placeHolder) { if (listFormField?.placeHolder) {
editorOptions = { defaultEditorOptions.placeholder = translate('::' + listFormField.placeHolder)
...editorOptions,
placeholder: translate('::' + listFormField.placeHolder),
}
} }
// Set defaultValue for @AUTONUMBER fields // Set defaultValue for @AUTONUMBER fields
@ -1033,10 +1035,22 @@ const Grid = (props: GridProps) => {
listFormField?.defaultValue === '@AUTONUMBER' && listFormField?.defaultValue === '@AUTONUMBER' &&
mode === 'new' mode === 'new'
) { ) {
editorOptions = { defaultEditorOptions.value = autoNumber()
...editorOptions, }
value: autoNumber(),
} editorOptions = {
...defaultEditorOptions,
...parsedEditorOptions,
...forcedEditorOptions,
}
if (editorOptions?.buttons) {
editorOptions.buttons = (editorOptions?.buttons || []).map((btn: any) => {
if (btn?.options?.onClick && typeof btn.options.onClick === 'string') {
btn.options.onClick = eval(`(${btn.options.onClick})`)
}
return btn
})
} }
const item: SimpleItemWithColData = { const item: SimpleItemWithColData = {

View file

@ -526,14 +526,21 @@ const Tree = (props: TreeProps) => {
const columnFormat = gridDto.columnFormats.find((column) => column.fieldName === fieldName) const columnFormat = gridDto.columnFormats.find((column) => column.fieldName === fieldName)
const isNewRow = Boolean((editor as any).row?.isNewRow) || mode === 'new' const isNewRow = Boolean((editor as any).row?.isNewRow) || mode === 'new'
const hasReadOnlyEditorOption = editor.editorOptions?.readOnly === true
const hasDisabledEditorOption = editor.editorOptions?.disabled === true
if ( if (
(isNewRow && columnFormat?.allowAdding === false) || (isNewRow && columnFormat?.allowAdding === false) ||
(!isNewRow && columnFormat?.allowEditing === false) (!isNewRow && columnFormat?.allowEditing === false)
) { ) {
editor.editorOptions.readOnly = true editor.editorOptions.readOnly = true
} else if (isNewRow && columnFormat?.allowAdding === true) { } else if (isNewRow && columnFormat?.allowAdding === true) {
editor.editorOptions.readOnly = false if (!hasReadOnlyEditorOption) {
editor.editorOptions.disabled = false editor.editorOptions.readOnly = false
}
if (!hasDisabledEditorOption) {
editor.editorOptions.disabled = false
}
} }
// Cascade disabled mantığı // Cascade disabled mantığı
@ -581,7 +588,17 @@ const Tree = (props: TreeProps) => {
try { try {
const editorInstance = formInstance.getEditor(col.fieldName!) const editorInstance = formInstance.getEditor(col.fieldName!)
if (editorInstance) { if (editorInstance) {
editorInstance.option('disabled', shouldDisable) const formItem = gridDto.gridOptions.editingFormDto
.flatMap((group) => group.items || [])
.find((i) => i.dataField === col.fieldName)
const editorOptions = formItem?.editorOptions
? JSON.parse(formItem.editorOptions)
: {}
editorInstance.option(
'disabled',
editorOptions?.disabled === true ? true : shouldDisable,
)
} }
} catch (err) { } catch (err) {
console.debug('Cascade disabled update skipped for', col.fieldName, err) console.debug('Cascade disabled update skipped for', col.fieldName, err)
@ -1082,22 +1099,10 @@ const Tree = (props: TreeProps) => {
// Helper function: item mapper // Helper function: item mapper
const mapFormItem = (i: EditingFormItemDto) => { const mapFormItem = (i: EditingFormItemDto) => {
let editorOptions: EditorOptionsWithButtons = {} let editorOptions: EditorOptionsWithButtons = {}
let parsedEditorOptions: EditorOptionsWithButtons = {}
const forcedEditorOptions: EditorOptionsWithButtons = {}
try { try {
editorOptions = i.editorOptions && JSON.parse(i.editorOptions) parsedEditorOptions = i.editorOptions ? JSON.parse(i.editorOptions) : {}
if (editorOptions?.buttons) {
editorOptions.buttons = (editorOptions?.buttons || []).map(
(btn: any) => {
if (
btn?.options?.onClick &&
typeof btn.options.onClick === 'string'
) {
btn.options.onClick = eval(`(${btn.options.onClick})`)
}
return btn
},
)
}
const rawFilter = searchParams?.get('filter') const rawFilter = searchParams?.get('filter')
if (rawFilter) { if (rawFilter) {
@ -1114,10 +1119,7 @@ const Tree = (props: TreeProps) => {
) )
if (!existsInExtra) { if (!existsInExtra) {
editorOptions = { forcedEditorOptions.readOnly = true
...editorOptions,
readOnly: true,
}
} }
} }
} }
@ -1128,28 +1130,44 @@ const Tree = (props: TreeProps) => {
(x: any) => x.fieldName === fieldName, (x: any) => x.fieldName === fieldName,
) )
const defaultEditorOptions: EditorOptionsWithButtons = {}
if (listFormField?.sourceDbType === DbTypeEnum.Date) { if (listFormField?.sourceDbType === DbTypeEnum.Date) {
editorOptions = { Object.assign(defaultEditorOptions, {
...{
type: 'date', type: 'date',
dateSerializationFormat: 'yyyy-MM-dd', dateSerializationFormat: 'yyyy-MM-dd',
displayFormat: 'shortDate', displayFormat: 'shortDate',
}, })
...editorOptions,
}
} else if ( } else if (
listFormField?.sourceDbType === DbTypeEnum.DateTime || listFormField?.sourceDbType === DbTypeEnum.DateTime ||
listFormField?.sourceDbType === DbTypeEnum.DateTime2 || listFormField?.sourceDbType === DbTypeEnum.DateTime2 ||
listFormField?.sourceDbType === DbTypeEnum.DateTimeOffset listFormField?.sourceDbType === DbTypeEnum.DateTimeOffset
) { ) {
editorOptions = { Object.assign(defaultEditorOptions, {
...{
type: 'datetime', type: 'datetime',
dateSerializationFormat: 'yyyy-MM-ddTHH:mm:ss', dateSerializationFormat: 'yyyy-MM-ddTHH:mm:ss',
displayFormat: 'shortDateShortTime', displayFormat: 'shortDateShortTime',
})
}
editorOptions = {
...defaultEditorOptions,
...parsedEditorOptions,
...forcedEditorOptions,
}
if (editorOptions?.buttons) {
editorOptions.buttons = (editorOptions?.buttons || []).map(
(btn: any) => {
if (
btn?.options?.onClick &&
typeof btn.options.onClick === 'string'
) {
btn.options.onClick = eval(`(${btn.options.onClick})`)
}
return btn
}, },
...editorOptions, )
}
} }
const item: SimpleItemWithColData = { const item: SimpleItemWithColData = {