diff --git a/ui/src/views/list/SchedulerView.tsx b/ui/src/views/list/SchedulerView.tsx index 15a0afae..49b197b4 100644 --- a/ui/src/views/list/SchedulerView.tsx +++ b/ui/src/views/list/SchedulerView.tsx @@ -25,7 +25,7 @@ import { usePermission } from '@/utils/hooks/usePermission' import { useListFormColumns } from './useListFormColumns' import { EditingFormItemDto } from '@/proxy/form/models' import useResponsive from '@/utils/hooks/useResponsive' -import { SimpleItemWithColData } from '../form/types' +import { colSpan } from '@/components/ui/Widget/iconList' interface SchedulerViewProps { listFormCode: string @@ -45,7 +45,6 @@ const SchedulerView = (props: SchedulerViewProps) => { const refListFormCode = useRef('') const widgetGroupRef = useRef(null) const { checkPermission } = usePermission() - const { smaller } = useResponsive() const [schedulerDataSource, setSchedulerDataSource] = useState>() const [gridDto, setGridDto] = useState() @@ -294,214 +293,127 @@ const SchedulerView = (props: SchedulerViewProps) => { .slice() .sort((a: any, b: any) => (a.order >= b.order ? 1 : -1)) + // Tüm tabbed items'ları topla (Grid'deki gibi) + const tabbedItems = sortedFormDto.filter((e: any) => e.itemType === 'tabbed') + + // Ortak item mapper fonksiyonu - hem group hem tab için kullanılır + const mapFormItem = (i: EditingFormItemDto) => { + let editorOptions: any = {} + try { + if (i.editorOptions) { + editorOptions = JSON.parse(i.editorOptions) + } + } catch {} + + const fieldName = i.dataField.split(':')[0] + const listFormField = gridDto.columnFormats.find((x: any) => x.fieldName === fieldName) + + // EditorType belirleme + let editorType: any = i.editorType2 || i.editorType + if (i.editorType2 === PlatformEditorTypes.dxGridBox) { + editorType = 'dxDropDownBox' + } else if (i.editorType2) { + editorType = i.editorType2 + } + + // Lookup DataSource oluştur + 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', + loadMode: 'raw', + load: async () => { + try { + const { dynamicFetch } = await import('@/services/form.service') + const response = await dynamicFetch('list-form-select/lookup', 'POST', null, { + listFormCode, + listFormFieldName: fieldName, + filters: [], + }) + return (response.data ?? []).map((a: any) => ({ + key: a.Key, + name: a.Name, + group: a.Group, + })) + } catch (error) { + console.error('Lookup load error:', error) + return [] + } + }, + }) + + editorOptions.valueExpr = 'key' + editorOptions.displayExpr = 'name' + } else if (lookup.dataSourceType === UiLookupDataSourceTypeEnum.StaticData) { + if (lookup.lookupQuery) { + try { + const staticData = JSON.parse(lookup.lookupQuery) + editorOptions.dataSource = staticData + editorOptions.valueExpr = lookup.valueExpr || 'key' + editorOptions.displayExpr = lookup.displayExpr || 'name' + } catch (error) { + console.error('Static data parse error:', error) + } + } + } + } + + // Validation rules + const validationRules: any[] = [] + if (i.isRequired) { + validationRules.push({ type: 'required' }) + } + + const item: any = { + dataField: i.dataField, + name: i.dataField, + editorType, + colSpan: i.colSpan, + editorOptions, + validationRules: validationRules.length > 0 ? validationRules : undefined, + } + + // Label sadece caption varsa ekle + if (listFormField?.captionName) { + item.label = { text: translate('::' + listFormField.captionName) } + } + + return item + } + sortedFormDto.forEach((group: any) => { // Items'ları da order'a göre sırala const sortedItems = (group.items || []) .slice() .sort((a: any, b: any) => (a.order >= b.order ? 1 : -1)) - const groupItems = sortedItems.map((i: EditingFormItemDto) => { - let editorOptions: any = {} - try { - if (i.editorOptions) { - editorOptions = JSON.parse(i.editorOptions) - } - } catch {} - - const fieldName = i.dataField.split(':')[0] - const listFormField = gridDto.columnFormats.find((x: any) => x.fieldName === fieldName) - - // EditorType belirleme - Grid'deki gibi - let editorType: any = i.editorType2 || i.editorType - if (i.editorType2 === PlatformEditorTypes.dxGridBox) { - editorType = 'dxDropDownBox' - } else if (i.editorType2) { - editorType = i.editorType2 - } - - // Lookup DataSource oluştur - 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', - loadMode: 'raw', - load: async () => { - try { - const { dynamicFetch } = await import('@/services/form.service') - const response = await dynamicFetch('list-form-select/lookup', 'POST', null, { - listFormCode, - listFormFieldName: fieldName, - filters: [], - }) - return (response.data ?? []).map((a: any) => ({ - key: a.Key, - name: a.Name, - group: a.Group, - })) - } catch (error) { - console.error('Lookup load error:', error) - return [] - } - }, - }) - - editorOptions.valueExpr = 'key' - editorOptions.displayExpr = 'name' - } else if (lookup.dataSourceType === UiLookupDataSourceTypeEnum.StaticData) { - if (lookup.lookupQuery) { - try { - const staticData = JSON.parse(lookup.lookupQuery) - editorOptions.dataSource = staticData - editorOptions.valueExpr = lookup.valueExpr || 'key' - editorOptions.displayExpr = lookup.displayExpr || 'name' - } catch (error) { - console.error('Static data parse error:', error) - } - } - } - } - - // Validation rules - const validationRules: any[] = [] - if (i.isRequired) { - validationRules.push({ type: 'required' }) - } - - const item: any = { - dataField: i.dataField, - name: i.dataField, - editorType, - colSpan: i.colSpan, - editorOptions, - validationRules: validationRules.length > 0 ? validationRules : undefined, - } - - // Label sadece caption varsa ekle - if (listFormField?.captionName) { - item.label = { text: translate('::' + listFormField.captionName) } - } - - return item - }) + const groupItems = sortedItems.map(mapFormItem) if (group.itemType === 'group') { // Grup kullanmadan direkt items'ları ekle - form'un colCount'u geçerli olsun formItems.push(...groupItems) - } else if (group.itemType === 'tabbed') { + } 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({ itemType: 'tabbed', - tabs: (group.tabs || []).map((tab: any) => { - // Tab items'larını da order'a göre sırala - const sortedTabItems = (tab.items || []) + // colCount ve colSpan kaldırıldı - tab'ın tüm genişliği kullanması için + 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)) return { - title: translate('::' + tab.title), - colCount: tab.colCount || 2, - items: sortedTabItems.map((i: EditingFormItemDto) => { - // Tab içindeki itemlar için de aynı mapping - let editorOptions: any = {} - try { - if (i.editorOptions) { - editorOptions = JSON.parse(i.editorOptions) - } - } catch {} - - const fieldName = i.dataField.split(':')[0] - const listFormField = gridDto.columnFormats.find( - (x: any) => x.fieldName === fieldName, - ) - - // EditorType belirleme - Grid'deki gibi - let editorType: any = i.editorType2 || i.editorType - if (i.editorType2 === PlatformEditorTypes.dxGridBox) { - editorType = 'dxDropDownBox' - } else if (i.editorType2) { - editorType = i.editorType2 - } - - 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', - loadMode: 'raw', - load: async () => { - try { - const { dynamicFetch } = await import('@/services/form.service') - const response = await dynamicFetch( - 'list-form-select/lookup', - 'POST', - null, - { - listFormCode, - listFormFieldName: fieldName, - filters: [], - }, - ) - return (response.data ?? []).map((a: any) => ({ - key: a.Key, - name: a.Name, - group: a.Group, - })) - } catch (error) { - console.error('Lookup load error:', error) - return [] - } - }, - }) - - editorOptions.valueExpr = 'key' - editorOptions.displayExpr = 'name' - } else if (lookup.dataSourceType === UiLookupDataSourceTypeEnum.StaticData) { - if (lookup.lookupQuery) { - try { - const staticData = JSON.parse(lookup.lookupQuery) - editorOptions.dataSource = staticData - editorOptions.valueExpr = lookup.valueExpr || 'key' - editorOptions.displayExpr = lookup.displayExpr || 'name' - } catch (error) { - console.error('Static data parse error:', error) - } - } - } - } - - const validationRules: any[] = [] - if (i.isRequired) { - validationRules.push({ type: 'required' }) - } - - const item: any = { - dataField: i.dataField, - name: i.dataField, - editorType, - colSpan: i.colSpan, - editorOptions, - validationRules: validationRules.length > 0 ? validationRules : undefined, - } - - // Label sadece caption varsa ekle - if (listFormField?.captionName) { - item.label = { text: translate('::' + listFormField.captionName) } - } - - return item - }), + title: translate('::' + tabbedItem.caption), // Backend'den caption geliyor + colCount: tabbedItem.colCount || 2, // Tab içindeki sütun sayısı + items: sortedTabItems.map(mapFormItem), } }), }) @@ -513,8 +425,10 @@ const SchedulerView = (props: SchedulerViewProps) => { } // 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: gridDto.gridOptions.editingFormDto?.[0]?.colCount || 2, + colCount: hasTabbedItems ? 1 : (gridDto.gridOptions.editingFormDto?.[0]?.colCount || 2), showValidationSummary: false, items: formItems, }