SchedulerView mode ve tabbed style düzenlemesi
This commit is contained in:
parent
cbfb5ccef6
commit
32720abac2
2 changed files with 151 additions and 87 deletions
|
|
@ -2801,11 +2801,11 @@ public class ListFormSeeder_Maintenance : IDataSeedContributor, ITransientDepend
|
|||
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson,
|
||||
PagerOptionJson = DefaultPagerOptionJson,
|
||||
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson,
|
||||
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 450, true, true, true, true, false),
|
||||
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 500, true, true, true, true, false),
|
||||
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
|
||||
new() {
|
||||
Order=1, ColCount=2, ColSpan=1, ItemType="group", Items= [
|
||||
new EditingFormItemDto { Order = 1, DataField = "Subject", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxTextArea },
|
||||
new EditingFormItemDto { Order = 1, DataField = "Subject", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
|
||||
new EditingFormItemDto { Order = 2, DataField = "WorkcenterId", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox },
|
||||
new EditingFormItemDto { Order = 3, DataField = "WorkorderTypeId", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox },
|
||||
new EditingFormItemDto { Order = 4, DataField = "Priority", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox },
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import Container from '@/components/shared/Container'
|
||||
import { DX_CLASSNAMES } from '@/constants/app.constant'
|
||||
import { GridDto, PlatformEditorTypes, UiLookupDataSourceTypeEnum } from '@/proxy/form/models'
|
||||
import {
|
||||
DbTypeEnum,
|
||||
GridDto,
|
||||
PlatformEditorTypes,
|
||||
UiLookupDataSourceTypeEnum,
|
||||
} from '@/proxy/form/models'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import Scheduler, {
|
||||
Editing,
|
||||
|
|
@ -14,7 +19,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'
|
|||
import { Helmet } from 'react-helmet'
|
||||
import { getList } from '@/services/form.service'
|
||||
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
|
||||
import { addCss, addJs } from './Utils'
|
||||
import { addCss, addJs, autoNumber } from './Utils'
|
||||
import { layoutTypes } from '../admin/listForm/edit/types'
|
||||
import WidgetGroup from '@/components/ui/Widget/WidgetGroup'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
|
|
@ -22,10 +27,10 @@ import { usePWA } from '@/utils/hooks/usePWA'
|
|||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import { Loading } from '@/components/shared'
|
||||
import { usePermission } from '@/utils/hooks/usePermission'
|
||||
import { useListFormColumns } from './useListFormColumns'
|
||||
import { EditingFormItemDto } from '@/proxy/form/models'
|
||||
import useResponsive from '@/utils/hooks/useResponsive'
|
||||
import { colSpan } from '@/components/ui/Widget/iconList'
|
||||
import { RowMode, SimpleItemWithColData } from '../form/types'
|
||||
import { captionize } from 'devextreme/core/utils/inflector'
|
||||
import { AppointmentFormOpeningEvent } from 'devextreme/ui/scheduler'
|
||||
|
||||
interface SchedulerViewProps {
|
||||
listFormCode: string
|
||||
|
|
@ -40,6 +45,7 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
|||
const { listFormCode, searchParams, isSubForm, level, gridDto: extGridDto } = props
|
||||
const { translate } = useLocalization()
|
||||
const isPwaMode = usePWA()
|
||||
const [mode, setMode] = useState<RowMode>('view')
|
||||
|
||||
const schedulerRef = useRef<SchedulerRef>()
|
||||
const refListFormCode = useRef('')
|
||||
|
|
@ -82,12 +88,6 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
|||
}, [listFormCode])
|
||||
|
||||
const { createSelectDataSource } = useListFormCustomDataSource({ gridRef: schedulerRef })
|
||||
const { getBandedColumns } = useListFormColumns({
|
||||
gridDto,
|
||||
listFormCode,
|
||||
isSubForm,
|
||||
gridRef: schedulerRef,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!gridDto) {
|
||||
|
|
@ -169,19 +169,31 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
|||
}, [])
|
||||
|
||||
const onAppointmentFormOpening = useCallback(
|
||||
(e: any) => {
|
||||
(e: AppointmentFormOpeningEvent) => {
|
||||
if (!gridDto) return
|
||||
|
||||
// Yeni appointment mı yoksa düzenleme mi kontrol et
|
||||
const isNewAppointment =
|
||||
!e.appointmentData ||
|
||||
(!e.appointmentData.id && !e.appointmentData[gridDto.gridOptions.keyFieldName || 'id'])
|
||||
|
||||
const currentMode = isNewAppointment ? 'new' : 'edit'
|
||||
setMode(currentMode)
|
||||
|
||||
// Popup ayarlarını her açılışta yeniden yapılandır
|
||||
e.popup.option('title', translate('::' + gridDto.gridOptions.editingOptionDto?.popup?.title))
|
||||
e.popup.option(
|
||||
'title',
|
||||
(currentMode === 'new' ? '✚ ' : '🖊️ ') +
|
||||
translate('::' + gridDto.gridOptions.editingOptionDto?.popup?.title),
|
||||
)
|
||||
e.popup.option('showTitle', gridDto.gridOptions.editingOptionDto?.popup?.showTitle)
|
||||
e.popup.option('width', gridDto.gridOptions.editingOptionDto?.popup?.width || 800)
|
||||
e.popup.option('height', gridDto.gridOptions.editingOptionDto?.popup?.height || 600)
|
||||
e.popup.option('width', gridDto.gridOptions.editingOptionDto?.popup?.width)
|
||||
e.popup.option('height', gridDto.gridOptions.editingOptionDto?.popup?.height)
|
||||
e.popup.option('resizeEnabled', gridDto.gridOptions.editingOptionDto?.popup?.resizeEnabled)
|
||||
e.popup.option('fullScreen', isPopupFullScreen)
|
||||
|
||||
// Toolbar butonlarını ekle
|
||||
const toolbarItems = [
|
||||
e.popup.option('toolbarItems', [
|
||||
{
|
||||
widget: 'dxButton',
|
||||
toolbar: 'bottom',
|
||||
|
|
@ -197,7 +209,7 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
|||
// Form verilerini al
|
||||
const formData = formInstance.option('formData')
|
||||
|
||||
try {0
|
||||
try {
|
||||
// Scheduler instance'ını al
|
||||
const scheduler = schedulerRef.current?.instance()
|
||||
|
||||
|
|
@ -266,27 +278,18 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
|||
e.popup.option('height', '100%')
|
||||
} else {
|
||||
e.popup.option('width', gridDto.gridOptions.editingOptionDto?.popup?.width || 600)
|
||||
e.popup.option('height', gridDto.gridOptions.editingOptionDto?.popup?.height || 'auto')
|
||||
}
|
||||
|
||||
// Button icon ve hint'i güncelle
|
||||
const button = e.popup._$element.find('.dx-toolbar-after .dx-button').last()
|
||||
if (button.length) {
|
||||
const buttonInstance = button.dxButton('instance')
|
||||
if (buttonInstance) {
|
||||
buttonInstance.option('icon', newFullScreenState ? 'collapse' : 'fullscreen')
|
||||
buttonInstance.option('hint', newFullScreenState ? translate('::Normal Boyut') : translate('::Tam Ekran'))
|
||||
}
|
||||
e.popup.option(
|
||||
'height',
|
||||
gridDto.gridOptions.editingOptionDto?.popup?.height || 'auto',
|
||||
)
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
e.popup.option('toolbarItems', toolbarItems)
|
||||
])
|
||||
|
||||
// EditingFormDto'dan form items oluştur
|
||||
const formItems: any[] = []
|
||||
const result: any[] = []
|
||||
|
||||
if (gridDto.gridOptions.editingFormDto?.length > 0) {
|
||||
const sortedFormDto = gridDto.gridOptions.editingFormDto
|
||||
|
|
@ -308,6 +311,42 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
|||
const fieldName = i.dataField.split(':')[0]
|
||||
const listFormField = gridDto.columnFormats.find((x: any) => x.fieldName === fieldName)
|
||||
|
||||
if (listFormField?.sourceDbType === DbTypeEnum.Date) {
|
||||
editorOptions = {
|
||||
...{
|
||||
type: 'date',
|
||||
dateSerializationFormat: 'yyyy-MM-dd',
|
||||
displayFormat: 'shortDate',
|
||||
},
|
||||
...editorOptions,
|
||||
}
|
||||
} else if (
|
||||
listFormField?.sourceDbType === DbTypeEnum.DateTime ||
|
||||
listFormField?.sourceDbType === DbTypeEnum.DateTime2 ||
|
||||
listFormField?.sourceDbType === DbTypeEnum.DateTimeOffset
|
||||
) {
|
||||
editorOptions = {
|
||||
...{
|
||||
type: 'datetime',
|
||||
dateSerializationFormat: 'yyyy-MM-ddTHH:mm:ssxxx',
|
||||
displayFormat: 'shortDateShortTime',
|
||||
},
|
||||
...editorOptions,
|
||||
}
|
||||
}
|
||||
|
||||
// Set defaultValue for @AUTONUMBER fields
|
||||
if (
|
||||
typeof listFormField?.defaultValue === 'string' &&
|
||||
listFormField?.defaultValue === '@AUTONUMBER' &&
|
||||
currentMode === 'new'
|
||||
) {
|
||||
editorOptions = {
|
||||
...editorOptions,
|
||||
value: autoNumber(),
|
||||
}
|
||||
}
|
||||
|
||||
// EditorType belirleme
|
||||
let editorType: any = i.editorType2 || i.editorType
|
||||
if (i.editorType2 === PlatformEditorTypes.dxGridBox) {
|
||||
|
|
@ -320,11 +359,6 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
|||
if (listFormField?.lookupDto) {
|
||||
const lookup = listFormField.lookupDto
|
||||
|
||||
// EditorType'ı dxSelectBox olarak ayarla
|
||||
if (!editorType || editorType === 'dxTextBox') {
|
||||
editorType = 'dxSelectBox'
|
||||
}
|
||||
|
||||
if (lookup.dataSourceType === UiLookupDataSourceTypeEnum.Query) {
|
||||
editorOptions.dataSource = new CustomStore({
|
||||
key: 'key',
|
||||
|
|
@ -365,81 +399,111 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
|||
}
|
||||
}
|
||||
|
||||
// Validation rules
|
||||
const validationRules: any[] = []
|
||||
if (i.isRequired) {
|
||||
validationRules.push({ type: 'required' })
|
||||
}
|
||||
|
||||
const item: any = {
|
||||
const item: SimpleItemWithColData = {
|
||||
canRead: listFormField?.canRead ?? false,
|
||||
canUpdate: listFormField?.canUpdate ?? false,
|
||||
canCreate: listFormField?.canCreate ?? false,
|
||||
canExport: listFormField?.canExport ?? false,
|
||||
dataField: i.dataField,
|
||||
name: i.dataField,
|
||||
editorType,
|
||||
editorType2: i.editorType2,
|
||||
editorType:
|
||||
i.editorType2 == PlatformEditorTypes.dxGridBox ? 'dxDropDownBox' : i.editorType2,
|
||||
colSpan: i.colSpan,
|
||||
isRequired: i.isRequired,
|
||||
editorOptions,
|
||||
validationRules: validationRules.length > 0 ? validationRules : undefined,
|
||||
editorScript: i.editorScript,
|
||||
}
|
||||
|
||||
// Label sadece caption varsa ekle
|
||||
if (listFormField?.captionName) {
|
||||
item.label = { text: translate('::' + listFormField.captionName) }
|
||||
if (i.dataField.indexOf(':') >= 0) {
|
||||
item.label = { text: captionize(i.dataField.split(':')[1]) }
|
||||
}
|
||||
|
||||
if ((currentMode == 'edit' && !item.canUpdate) || (currentMode == 'new' && !item.canCreate)) {
|
||||
item.editorOptions = {
|
||||
...item.editorOptions,
|
||||
readOnly: true,
|
||||
}
|
||||
}
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
sortedFormDto.forEach((group: any) => {
|
||||
sortedFormDto.forEach((e: any) => {
|
||||
// Items'ları da order'a göre sırala
|
||||
const sortedItems = (group.items || [])
|
||||
const sortedItems = (e.items || [])
|
||||
.slice()
|
||||
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||
|
||||
const groupItems = sortedItems.map(mapFormItem)
|
||||
|
||||
if (group.itemType === 'group') {
|
||||
if (e.itemType !== 'tabbed') {
|
||||
// Grup kullanmadan direkt items'ları ekle - form'un colCount'u geçerli olsun
|
||||
formItems.push(...groupItems)
|
||||
} else if (group.itemType === 'tabbed' && tabbedItems.length > 0 && group === tabbedItems[0]) {
|
||||
// Tüm tabbed items'ları tek bir tabbed item olarak ekle (Grid'deki gibi)
|
||||
formItems.push({
|
||||
result.push(...groupItems)
|
||||
} else if (e.itemType === 'tabbed' && tabbedItems.length > 0 && e === tabbedItems[0]) {
|
||||
// Tabbed için caption OLMAMALI - sadece tabs array içinde title kullan
|
||||
result.push({
|
||||
itemType: 'tabbed',
|
||||
// colCount ve colSpan kaldırıldı - tab'ın tüm genişliği kullanması için
|
||||
// colCount tabbed item için OLMAMALI - sadece colSpan
|
||||
colSpan: 1,
|
||||
// caption kullanma! Tabs içindeki title'lar yeterli
|
||||
tabs: tabbedItems.map((tabbedItem: any) => {
|
||||
// Tab items'larını order'a göre sırala
|
||||
const sortedTabItems = (tabbedItem.items || [])
|
||||
.slice()
|
||||
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||
// Backend'den gelen colCount ve colSpan değerlerini kullan
|
||||
const effectiveColCount = tabbedItem.colCount || 2
|
||||
|
||||
return {
|
||||
title: translate('::' + tabbedItem.caption), // Backend'den caption geliyor
|
||||
colCount: tabbedItem.colCount || 2, // Tab içindeki sütun sayısı
|
||||
items: sortedTabItems.map(mapFormItem),
|
||||
title: tabbedItem.caption, // Her tab'ın title'ı
|
||||
colCount: effectiveColCount,
|
||||
items: tabbedItem.items
|
||||
?.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||
.map(mapFormItem)
|
||||
.filter((a: any) => {
|
||||
if (currentMode === 'new') {
|
||||
return a.canCreate || a.canRead
|
||||
} else if (currentMode === 'edit') {
|
||||
return a.canUpdate || a.canRead
|
||||
}
|
||||
return false
|
||||
}),
|
||||
}
|
||||
}),
|
||||
})
|
||||
} else {
|
||||
// No group, add items directly
|
||||
formItems.push(...groupItems)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Form'u tamamen yeniden yapılandır
|
||||
// Tabbed varsa form colCount 1, yoksa backend'den gelen değer
|
||||
const hasTabbedItems = formItems.some((item: any) => item.itemType === 'tabbed')
|
||||
const formConfig = {
|
||||
colCount: hasTabbedItems ? 1 : (gridDto.gridOptions.editingFormDto?.[0]?.colCount || 2),
|
||||
showValidationSummary: false,
|
||||
items: formItems,
|
||||
}
|
||||
const hasTabbedItems = result.some((item: any) => item.itemType === 'tabbed')
|
||||
|
||||
// Form'u tamamen yeniden baştan yapılandır
|
||||
e.form.option('colCount', formConfig.colCount)
|
||||
e.form.option('showValidationSummary', formConfig.showValidationSummary)
|
||||
e.form.option('items', formConfig.items)
|
||||
e.form.option(
|
||||
'colCount',
|
||||
hasTabbedItems ? 1 : gridDto.gridOptions.editingFormDto?.[0]?.colCount || 2,
|
||||
)
|
||||
e.form.option(
|
||||
'colCount',
|
||||
hasTabbedItems ? 1 : gridDto.gridOptions.editingFormDto?.[0]?.colCount || 2,
|
||||
)
|
||||
e.form.option('showValidationSummary', false)
|
||||
e.form.option('items', result)
|
||||
|
||||
// Yeni versiyonlarda bu şekilde Style değiştirme işlemi yapmak zorunda olmayabiliriz.
|
||||
// Yani geçici olarak eklenmiştir.
|
||||
// Tabbed varsa belirli class'lara sahip elementi bul ve flex-direction'ı değiştir
|
||||
if (hasTabbedItems) {
|
||||
setTimeout(() => {
|
||||
const targetElement = document.querySelector('.dx-item-content.dx-box-item-content.dx-box-flex.dx-box.dx-widget.dx-collection')
|
||||
if (targetElement) {
|
||||
const htmlElement = targetElement as HTMLElement
|
||||
|
||||
// Mevcut style'ı al ve flex-direction: row'u column'a çevir
|
||||
const currentStyle = htmlElement.getAttribute('style') || ''
|
||||
const updatedStyle = currentStyle.replace(/flex-direction:\s*row/gi, 'flex-direction: column')
|
||||
htmlElement.setAttribute('style', updatedStyle)
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
|
||||
// Form'u repaint et
|
||||
e.form.repaint()
|
||||
},
|
||||
[gridDto, translate, isPopupFullScreen, listFormCode],
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue