From 226e71d1a7f22bcb1989d85f4cd1059aa0711c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Fri, 7 Nov 2025 17:06:17 +0300 Subject: [PATCH] =?UTF-8?q?Grid=20Popup=20Tabbed=20=C3=B6zelli=C4=9Fi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/index.css | 5 + ui/src/views/list/Grid.tsx | 306 +++++++++++++++++++++---------------- 2 files changed, 182 insertions(+), 129 deletions(-) diff --git a/ui/src/index.css b/ui/src/index.css index 6607deda..5bfccd88 100644 --- a/ui/src/index.css +++ b/ui/src/index.css @@ -4,6 +4,11 @@ body { font-size: 14px; /* body’ye font-size uygulanmaz */ } +/* Popup formun içerisindeki Tabbed Item Title */ +.dx-tab-text-span-pseudo { + display: none !important; +} + .big-button { font-size: 16px !important; } diff --git a/ui/src/views/list/Grid.tsx b/ui/src/views/list/Grid.tsx index 544afd38..e63e9129 100644 --- a/ui/src/views/list/Grid.tsx +++ b/ui/src/views/list/Grid.tsx @@ -816,6 +816,7 @@ const Grid = (props: GridProps) => { fullScreen: gridDto.gridOptions.editingOptionDto?.popup?.fullScreen, }} form={{ + colCount: 1, onFieldDataChanged: (e) => { if (e.dataField) { const formItem = gridDto.gridOptions.editingFormDto @@ -832,150 +833,197 @@ const Grid = (props: GridProps) => { }, items: gridDto.gridOptions.editingFormDto?.length > 0 - ? gridDto.gridOptions.editingFormDto - ?.sort((a: any, b: any) => { - return a.order >= b.order ? 1 : -1 - }) - .map((e: any) => { - return { - itemType: e.itemType, - colCount: e.colCount, - colSpan: e.colSpan, - caption: e.caption, - items: e.items - ?.sort((a: any, b: any) => { - return a.order >= b.order ? 1 : -1 - }) - .map((i: EditingFormItemDto) => { - let editorOptions: EditorOptionsWithButtons = {} - try { - editorOptions = i.editorOptions && JSON.parse(i.editorOptions) + ? (() => { + const sortedFormDto = gridDto.gridOptions.editingFormDto + .slice() + .sort((a: any, b: any) => (a.order >= b.order ? 1 : -1)) - if (editorOptions?.buttons) { - /* - { - "buttons": [ - { - "name": "custom", - "location": "after", - "options": { - "icon": "plus", - "onClick": "function(e) { alert('Button clicked for ' + formData[i.dataField]); }" - } - } - ] - } - */ - 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 - }, - ) + // Tabbed item'ları grupla + const tabbedItems = sortedFormDto.filter((e: any) => e.itemType === 'tabbed') + const result: any[] = [] + + // Helper function: item mapper + const mapFormItem = (i: EditingFormItemDto) => { + let editorOptions: EditorOptionsWithButtons = {} + try { + editorOptions = 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 + }, + ) + } - // Eğer default value varsa, bu editörü readonly yapıyoruz - const rawFilter = searchParams?.get('filter') - if (rawFilter) { - const parsed = JSON.parse(rawFilter) - const filters = extractSearchParamsFields(parsed) + const rawFilter = searchParams?.get('filter') + if (rawFilter) { + const parsed = JSON.parse(rawFilter) + const filters = extractSearchParamsFields(parsed) - const hasFilter = filters.some( - ([field, op, val]) => field === i.dataField, - ) + const hasFilter = filters.some( + ([field, op, val]) => field === i.dataField, + ) - if (hasFilter) { - const existsInExtra = extraFilters.some( - (f) => f.fieldName === i.dataField && !!f.value, - ) - - if (!existsInExtra) { - editorOptions = { - ...editorOptions, - readOnly: true, - } - } - } - } - } catch {} - const fieldName = i.dataField.split(':')[0] - const listFormField = gridDto.columnFormats.find( - (x: any) => x.fieldName === fieldName, + if (hasFilter) { + const existsInExtra = extraFilters.some( + (f) => f.fieldName === i.dataField && !!f.value, ) - if (listFormField?.sourceDbType === DbTypeEnum.Date) { + + if (!existsInExtra) { 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, - } - } - 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, - editorType2: i.editorType2, - editorType: - i.editorType2 == PlatformEditorTypes.dxGridBox - ? 'dxDropDownBox' - : i.editorType2, - colSpan: i.colSpan, - isRequired: i.isRequired, - editorOptions, - editorScript: i.editorScript, - } - if (i.dataField.indexOf(':') >= 0) { - item.label = { text: captionize(i.dataField.split(':')[1]) } - } - if ( - (mode == 'edit' && !item.canUpdate) || - (mode == 'new' && !item.canCreate) - ) { - item.editorOptions = { - ...item.editorOptions, readOnly: true, } } + } + } + } catch {} - return item - }) - .filter((a: any) => { - // return a.canRead - if (mode === 'view') { - return a.canRead - } else if (mode === 'new') { - return a.canCreate || a.canRead - } else if (mode === 'edit') { - return a.canUpdate || a.canRead - } else { - return false + 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, + } + } + + 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, + editorType2: i.editorType2, + editorType: + i.editorType2 == PlatformEditorTypes.dxGridBox + ? 'dxDropDownBox' + : i.editorType2, + colSpan: i.colSpan, + isRequired: i.isRequired, + editorOptions, + editorScript: i.editorScript, + } + + if (i.dataField.indexOf(':') >= 0) { + item.label = { text: captionize(i.dataField.split(':')[1]) } + } + + if ( + (mode == 'edit' && !item.canUpdate) || + (mode == 'new' && !item.canCreate) + ) { + item.editorOptions = { + ...item.editorOptions, + readOnly: true, + } + } + + return item + } + + sortedFormDto.forEach((e: any) => { + if (e.itemType !== 'tabbed') { + // colCount: max(endpoint.colCount, max(item.colSpan)) + const maxItemColSpan = Math.max( + ...(e.items?.map((i: any) => i.colSpan || 1) || [1]), + ) + const effectiveColCount = Math.max( + maxItemColSpan, + e.colCount || 1, + ) + + result.push({ + itemType: e.itemType, + colCount: effectiveColCount, + colSpan: e.colSpan, + caption: e.caption, // Group'larda caption olmalı + items: e.items + ?.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1)) + .map(mapFormItem) + .filter((a: any) => { + if (mode === 'view') { + return a.canRead + } else if (mode === 'new') { + return a.canCreate || a.canRead + } else if (mode === 'edit') { + return a.canUpdate || a.canRead + } else { + return false + } + }), + }) + } else if (tabbedItems.length > 0 && e === tabbedItems[0]) { + // Tabbed için caption OLMAMALI - sadece tabs array içinde title kullan + result.push({ + itemType: 'tabbed', + colCount: 1, + colSpan: 1, + // caption kullanma! Tabs içindeki title'lar yeterli + tabs: tabbedItems.map((tabbedItem: any) => { + // Tab için colCount: max(endpoint.colCount, max(item.colSpan)) + const maxItemColSpan = Math.max( + ...(tabbedItem.items?.map((i: any) => i.colSpan || 1) || [1]), + ) + const effectiveColCount = Math.max( + maxItemColSpan, + tabbedItem.colCount || 1, + ) + + + return { + 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 (mode === 'view') { + return a.canRead + } else if (mode === 'new') { + return a.canCreate || a.canRead + } else if (mode === 'edit') { + return a.canUpdate || a.canRead + } else { + return false + } + }), } }), - } as GroupItem + }) + } }) + + return result + })() : undefined, }} >