2025-05-06 06:45:49 +00:00
|
|
|
|
import Container from '@/components/shared/Container'
|
|
|
|
|
|
import { Dialog, Notification, toast } from '@/components/ui'
|
|
|
|
|
|
import { DX_CLASSNAMES } from '@/constants/app.constant'
|
|
|
|
|
|
import {
|
|
|
|
|
|
DbTypeEnum,
|
|
|
|
|
|
EditingFormItemDto,
|
|
|
|
|
|
GridDto,
|
|
|
|
|
|
ListFormCustomizationTypeEnum,
|
|
|
|
|
|
PlatformEditorTypes,
|
2025-09-12 11:26:35 +00:00
|
|
|
|
WidgetGroupDto,
|
2025-08-12 08:39:06 +00:00
|
|
|
|
} from '@/proxy/form/models'
|
|
|
|
|
|
import { getList } from '@/services/form.service'
|
2025-05-06 06:45:49 +00:00
|
|
|
|
import {
|
|
|
|
|
|
getListFormCustomization,
|
|
|
|
|
|
postListFormCustomization,
|
2025-08-12 08:39:06 +00:00
|
|
|
|
} from '@/services/list-form-customization.service'
|
2025-05-06 06:45:49 +00:00
|
|
|
|
import { useListFormColumns } from '@/shared/useListFormColumns'
|
|
|
|
|
|
import { useListFormCustomDataSource } from '@/shared/useListFormCustomDataSource'
|
|
|
|
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|
|
|
|
|
import useResponsive from '@/utils/hooks/useResponsive'
|
|
|
|
|
|
import { Template } from 'devextreme-react/core/template'
|
|
|
|
|
|
import DataGrid, {
|
|
|
|
|
|
ColumnChooser,
|
|
|
|
|
|
ColumnFixing,
|
|
|
|
|
|
DataGridTypes,
|
|
|
|
|
|
Editing,
|
|
|
|
|
|
Export,
|
|
|
|
|
|
FilterPanel,
|
|
|
|
|
|
FilterRow,
|
|
|
|
|
|
Grouping,
|
|
|
|
|
|
GroupItem as GroupItemDx,
|
|
|
|
|
|
GroupPanel,
|
|
|
|
|
|
HeaderFilter,
|
|
|
|
|
|
IStateStoringProps,
|
|
|
|
|
|
LoadPanel,
|
|
|
|
|
|
Pager,
|
|
|
|
|
|
Scrolling,
|
|
|
|
|
|
SearchPanel,
|
|
|
|
|
|
Selection,
|
|
|
|
|
|
Sorting,
|
|
|
|
|
|
Summary,
|
|
|
|
|
|
Toolbar,
|
2025-07-28 12:48:30 +00:00
|
|
|
|
TotalItem,
|
2025-05-06 06:45:49 +00:00
|
|
|
|
} from 'devextreme-react/data-grid'
|
|
|
|
|
|
import { Item } from 'devextreme-react/toolbar'
|
|
|
|
|
|
import { DataType } from 'devextreme/common'
|
|
|
|
|
|
import { captionize } from 'devextreme/core/utils/inflector'
|
|
|
|
|
|
import CustomStore from 'devextreme/data/custom_store'
|
|
|
|
|
|
import { GroupItem } from 'devextreme/ui/form'
|
|
|
|
|
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
|
|
|
|
import { Helmet } from 'react-helmet'
|
|
|
|
|
|
import SubForms from '../form/SubForms'
|
|
|
|
|
|
import { RowMode, SimpleItemWithColData } from '../form/types'
|
2025-09-18 22:09:58 +00:00
|
|
|
|
import { GridColumnData } from './GridColumnData'
|
2025-05-06 06:45:49 +00:00
|
|
|
|
import GridFilterDialogs from './GridFilterDialogs'
|
|
|
|
|
|
import {
|
|
|
|
|
|
addCss,
|
|
|
|
|
|
addJs,
|
|
|
|
|
|
controlStyleCondition,
|
2025-09-18 22:09:58 +00:00
|
|
|
|
GridExtraFilterState,
|
2025-05-06 06:45:49 +00:00
|
|
|
|
setFormEditingExtraItemValues,
|
|
|
|
|
|
setGridPanelColor,
|
|
|
|
|
|
} from './Utils'
|
|
|
|
|
|
import { GridBoxEditorComponent } from './editors/GridBoxEditorComponent'
|
|
|
|
|
|
import { TagBoxEditorComponent } from './editors/TagBoxEditorComponent'
|
|
|
|
|
|
import { useFilters } from './useFilters'
|
|
|
|
|
|
import { useToolbar } from './useToolbar'
|
2025-08-11 06:34:44 +00:00
|
|
|
|
import { ImportDashboard } from '@/components/importManager/ImportDashboard'
|
2025-09-12 11:26:35 +00:00
|
|
|
|
import WidgetGroup from '@/components/ui/Widget/WidgetGroup'
|
2025-09-17 14:13:48 +00:00
|
|
|
|
import { GridExtraFilterToolbar } from './GridExtraFilterToolbar'
|
2025-05-06 06:45:49 +00:00
|
|
|
|
|
|
|
|
|
|
interface GridProps {
|
|
|
|
|
|
listFormCode: string
|
|
|
|
|
|
searchParams?: URLSearchParams
|
|
|
|
|
|
isSubForm?: boolean
|
|
|
|
|
|
level?: number
|
|
|
|
|
|
refreshData?: () => Promise<void>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' // kullanici tanimli gridState ile islem gormus gridin paneline ait renk
|
|
|
|
|
|
|
|
|
|
|
|
const Grid = (props: GridProps) => {
|
|
|
|
|
|
const { listFormCode, searchParams, isSubForm, level } = props
|
|
|
|
|
|
const { translate } = useLocalization()
|
|
|
|
|
|
const { smaller } = useResponsive()
|
|
|
|
|
|
|
|
|
|
|
|
const gridRef = useRef<DataGrid>()
|
|
|
|
|
|
const refListFormCode = useRef('')
|
|
|
|
|
|
|
|
|
|
|
|
const [gridDto, setGridDto] = useState<GridDto>()
|
|
|
|
|
|
const [gridDataSource, setGridDataSource] = useState<CustomStore<any, any>>()
|
|
|
|
|
|
const [columnData, setColumnData] = useState<GridColumnData[]>()
|
|
|
|
|
|
const [formData, setFormData] = useState<any>()
|
|
|
|
|
|
const [mode, setMode] = useState<RowMode>('view')
|
2025-09-12 11:26:35 +00:00
|
|
|
|
const [widgetGroups, setWidgetGroups] = useState<WidgetGroupDto[]>([])
|
2025-09-17 14:13:48 +00:00
|
|
|
|
const [extraFilters, setExtraFilters] = useState<GridExtraFilterState[]>([])
|
2025-05-06 06:45:49 +00:00
|
|
|
|
|
2025-08-18 14:55:51 +00:00
|
|
|
|
const preloadExportLibs = () => {
|
|
|
|
|
|
import('exceljs')
|
|
|
|
|
|
import('file-saver')
|
|
|
|
|
|
import('devextreme/excel_exporter')
|
|
|
|
|
|
import('jspdf')
|
|
|
|
|
|
import('devextreme/pdf_exporter')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-19 13:30:19 +00:00
|
|
|
|
const defaultSearchParamsFilter = useRef<string | null>(null)
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
// sadece 1 kere açılışta al
|
|
|
|
|
|
if (!defaultSearchParamsFilter.current) {
|
|
|
|
|
|
defaultSearchParamsFilter.current = searchParams?.get('filter') ?? null
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [searchParams])
|
|
|
|
|
|
|
2025-05-06 06:45:49 +00:00
|
|
|
|
const { toolbarData, toolbarModalData, setToolbarModalData } = useToolbar({
|
|
|
|
|
|
gridDto,
|
|
|
|
|
|
listFormCode,
|
|
|
|
|
|
getSelectedRowKeys,
|
|
|
|
|
|
getSelectedRowsData,
|
|
|
|
|
|
refreshData,
|
|
|
|
|
|
getFilter,
|
2025-09-17 14:13:48 +00:00
|
|
|
|
extraFilters,
|
|
|
|
|
|
setExtraFilters,
|
2025-05-06 06:45:49 +00:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const { filterToolbarData, ...filterData } = useFilters({
|
|
|
|
|
|
gridDto,
|
|
|
|
|
|
gridRef,
|
|
|
|
|
|
listFormCode,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const { createSelectDataSource } = useListFormCustomDataSource({ gridRef })
|
|
|
|
|
|
const { getBandedColumns } = useListFormColumns({
|
|
|
|
|
|
gridDto,
|
|
|
|
|
|
listFormCode,
|
|
|
|
|
|
isSubForm,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
async function getSelectedRowKeys() {
|
|
|
|
|
|
const grd = gridRef.current?.instance
|
|
|
|
|
|
if (!grd) {
|
|
|
|
|
|
return []
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return await grd.getSelectedRowKeys()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getSelectedRowsData() {
|
|
|
|
|
|
const grd = gridRef.current?.instance
|
|
|
|
|
|
if (!grd) {
|
|
|
|
|
|
return []
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return grd.getSelectedRowsData()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function refreshData() {
|
|
|
|
|
|
gridRef.current?.instance.refresh()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getFilter() {
|
|
|
|
|
|
const grd = gridRef.current?.instance
|
|
|
|
|
|
if (!grd) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return grd.getCombinedFilter()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onSelectionChanged(data: any) {
|
|
|
|
|
|
const grdOpt = gridDto?.gridOptions
|
|
|
|
|
|
const grd = gridRef.current?.instance
|
|
|
|
|
|
if (!grdOpt || !grd) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// kullanicinin yetkisi varsa ve birden fazla kayit secili ise coklu silme gorunsun
|
|
|
|
|
|
if (grdOpt.editingOptionDto?.allowDeleting) {
|
|
|
|
|
|
// && abp.auth.isGranted(grdOpt.permissionDto?.d)
|
|
|
|
|
|
// kullanicinin silme yetkisi var ise
|
|
|
|
|
|
const opt = grd.option('toolbar')
|
|
|
|
|
|
const deleteSelectedRecordsIndex = opt?.items
|
|
|
|
|
|
?.map((e: any) => e.name)
|
|
|
|
|
|
.indexOf('deleteSelectedRecords')
|
|
|
|
|
|
// deleteSelectedRecords ismindeki custom butonun index degerini bul
|
|
|
|
|
|
|
|
|
|
|
|
grd.option(
|
|
|
|
|
|
`toolbar.items[${deleteSelectedRecordsIndex}].options.visible`,
|
|
|
|
|
|
data.selectedRowsData.length > 1,
|
|
|
|
|
|
) // birden fazla kayit secilmis ise gorunsun
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SubForm'ları gösterebilmek için secili satiri formData'ya at
|
|
|
|
|
|
if (data.selectedRowsData.length) {
|
|
|
|
|
|
setFormData(data.selectedRowsData[0])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onCellPrepared(e: any) {
|
|
|
|
|
|
const columnFormats = gridDto?.columnFormats
|
|
|
|
|
|
if (!columnFormats) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// satir, hucre yada header vb. kisimlara conditional style uygulamak icin
|
|
|
|
|
|
for (let indxCol = 0; indxCol < columnFormats.length; indxCol++) {
|
|
|
|
|
|
const colFormat = columnFormats[indxCol]
|
|
|
|
|
|
for (let indxStyl = 0; indxStyl < colFormat.columnStylingDto.length; indxStyl++) {
|
|
|
|
|
|
const colStyle = colFormat.columnStylingDto[indxStyl] // uygulanacak style
|
|
|
|
|
|
if (e.rowType == colStyle.rowType) {
|
|
|
|
|
|
// header, filter, data, group, summaries ..her birisine style uygulanabilir
|
|
|
|
|
|
// style bütün satıra uygulansın olarak seçili ise yada sadece ilgili field üzerinde ise
|
|
|
|
|
|
if (colStyle.useRow || e.column.dataField == colFormat.fieldName) {
|
|
|
|
|
|
if (
|
|
|
|
|
|
!colStyle.conditionValue ||
|
|
|
|
|
|
controlStyleCondition(e.data, colFormat.fieldName, colStyle)
|
|
|
|
|
|
) {
|
|
|
|
|
|
// css sınıf ismi var ise uygula
|
|
|
|
|
|
if (colStyle.cssClassName) {
|
|
|
|
|
|
e.cellElement.addClass(colStyle.cssClassName)
|
|
|
|
|
|
}
|
|
|
|
|
|
// css inline style var ise uygula
|
|
|
|
|
|
if (colStyle.cssStyles) {
|
|
|
|
|
|
e.cellElement.attr('style', e.cellElement.attr('style') + ';' + colStyle.cssStyles)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onInitNewRow(e: any) {
|
|
|
|
|
|
if (!gridDto?.columnFormats) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setMode('new')
|
|
|
|
|
|
|
|
|
|
|
|
for (const colFormat of gridDto?.columnFormats) {
|
|
|
|
|
|
if (!colFormat.fieldName) {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Grid'den gelen columnFormat'ları kullanarak default değerleri set et
|
|
|
|
|
|
if (colFormat.defaultValue != null) {
|
|
|
|
|
|
e.data[colFormat.fieldName] = colFormat.defaultValue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// URL'den veya Component Prop'dan gelen parametreleri set et
|
|
|
|
|
|
if (!searchParams) {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2025-09-19 13:30:19 +00:00
|
|
|
|
|
|
|
|
|
|
const filterValue = searchParams.get('filter')
|
|
|
|
|
|
|
|
|
|
|
|
if (filterValue) {
|
|
|
|
|
|
if (filterValue.includes(colFormat.fieldName)) {
|
|
|
|
|
|
const parsed = JSON.parse(filterValue) as [string, string, any]
|
|
|
|
|
|
const [field, op, val] = parsed
|
|
|
|
|
|
|
|
|
|
|
|
if (field === colFormat.fieldName) {
|
|
|
|
|
|
const dType = colFormat.dataType as DataType
|
|
|
|
|
|
switch (dType) {
|
|
|
|
|
|
case 'date':
|
|
|
|
|
|
case 'datetime':
|
|
|
|
|
|
e.data[colFormat.fieldName] = new Date(val)
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'number':
|
|
|
|
|
|
e.data[colFormat.fieldName] = Number(val)
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'boolean':
|
|
|
|
|
|
e.data[colFormat.fieldName] = val === true || val === 'true'
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'object':
|
|
|
|
|
|
try {
|
|
|
|
|
|
e.data[colFormat.fieldName] = JSON.parse(val)
|
|
|
|
|
|
} catch {}
|
|
|
|
|
|
break
|
|
|
|
|
|
default:
|
|
|
|
|
|
e.data[colFormat.fieldName] = val
|
|
|
|
|
|
break
|
2025-05-06 06:45:49 +00:00
|
|
|
|
}
|
2025-09-19 13:30:19 +00:00
|
|
|
|
}
|
2025-05-06 06:45:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onRowInserting(e: DataGridTypes.RowInsertingEvent<any, any>) {
|
|
|
|
|
|
e.data = setFormEditingExtraItemValues(e.data)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onRowUpdating(e: DataGridTypes.RowUpdatingEvent<any, any>) {
|
|
|
|
|
|
if (gridDto?.gridOptions.editingOptionDto?.sendOnlyChangedFormValuesUpdate) {
|
|
|
|
|
|
if (Object.keys(e.newData).some((a) => a.includes(':'))) {
|
|
|
|
|
|
Object.keys(e.oldData).forEach((col) => {
|
|
|
|
|
|
if (col.includes(':')) {
|
|
|
|
|
|
e.newData[col] = e.newData[col] ?? e.oldData[col]
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
e.newData = setFormEditingExtraItemValues(e.newData)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
let newData = { ...e.oldData, ...e.newData }
|
|
|
|
|
|
newData = setFormEditingExtraItemValues(newData)
|
|
|
|
|
|
Object.keys(newData).forEach((key) => {
|
|
|
|
|
|
if (key.includes(':')) {
|
|
|
|
|
|
delete newData[key]
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
e.newData = newData
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (gridDto?.gridOptions.keyFieldName) {
|
|
|
|
|
|
delete e.newData[gridDto?.gridOptions.keyFieldName]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onEditingStart(e: DataGridTypes.EditingStartEvent<any, any>) {
|
|
|
|
|
|
setMode('edit')
|
|
|
|
|
|
const columns = e.component.option('columns') as GridColumnData[]
|
|
|
|
|
|
// FormEditingExtraItem field ise datayı doldur
|
|
|
|
|
|
columns?.forEach((col) => {
|
|
|
|
|
|
if (!col.dataField?.includes(':')) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const field = col.dataField.split(':')
|
|
|
|
|
|
if (!e.data[field[0]]) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const json = JSON.parse(e.data[field[0]])
|
|
|
|
|
|
e.data[col.dataField] = json[field[1]]
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onDataErrorOccurred(e: DataGridTypes.DataErrorOccurredEvent<any, any>) {
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="danger" duration={2000}>
|
|
|
|
|
|
{e.error?.message}
|
|
|
|
|
|
</Notification>,
|
|
|
|
|
|
{
|
2025-09-01 14:07:03 +00:00
|
|
|
|
placement: 'top-end',
|
2025-05-06 06:45:49 +00:00
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const customSaveState = useCallback(
|
|
|
|
|
|
(state: any) =>
|
|
|
|
|
|
postListFormCustomization({
|
|
|
|
|
|
listFormCode: listFormCode,
|
|
|
|
|
|
customizationType: ListFormCustomizationTypeEnum.GridState,
|
|
|
|
|
|
filterName: `list-${gridRef.current?.instance.option('stateStoring')?.storageKey ?? ''}`,
|
|
|
|
|
|
customizationData: JSON.stringify(state),
|
|
|
|
|
|
}).then(() => {
|
|
|
|
|
|
setGridPanelColor(statedGridPanelColor)
|
|
|
|
|
|
}),
|
|
|
|
|
|
[listFormCode],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const customLoadState = useCallback(
|
|
|
|
|
|
() =>
|
|
|
|
|
|
getListFormCustomization(
|
|
|
|
|
|
listFormCode,
|
|
|
|
|
|
ListFormCustomizationTypeEnum.GridState,
|
|
|
|
|
|
`list-${gridRef.current?.instance.option('stateStoring')?.storageKey ?? ''}`,
|
|
|
|
|
|
).then((response: any) => {
|
|
|
|
|
|
setGridPanelColor(statedGridPanelColor)
|
|
|
|
|
|
if (response.data?.length > 0) {
|
|
|
|
|
|
return JSON.parse(response.data[0].customizationData)
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
[listFormCode],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (gridRef?.current) {
|
|
|
|
|
|
gridRef.current.instance.option('columns', undefined)
|
|
|
|
|
|
gridRef.current.instance.option('remoteOperations', false)
|
|
|
|
|
|
gridRef.current.instance.option('dataSource', undefined)
|
|
|
|
|
|
gridRef.current.instance.state(null)
|
2025-09-19 13:30:19 +00:00
|
|
|
|
|
|
|
|
|
|
//bir önceki gridin filtreleri kalmasın
|
|
|
|
|
|
setExtraFilters([])
|
|
|
|
|
|
setWidgetGroups([])
|
2025-05-06 06:45:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const initializeGrid = async () => {
|
|
|
|
|
|
const response = await getList({ listFormCode })
|
|
|
|
|
|
setGridDto(response.data)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (refListFormCode.current !== listFormCode) {
|
|
|
|
|
|
initializeGrid()
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [listFormCode])
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (!gridDto) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set js and css
|
|
|
|
|
|
const grdOpt = gridDto.gridOptions
|
|
|
|
|
|
if (grdOpt.customJsSources.length) {
|
|
|
|
|
|
for (const js of grdOpt.customJsSources) {
|
|
|
|
|
|
addJs(js)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (grdOpt.customStyleSources.length) {
|
|
|
|
|
|
for (const css of grdOpt.customStyleSources) {
|
|
|
|
|
|
addCss(css)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-19 13:30:19 +00:00
|
|
|
|
|
|
|
|
|
|
if (gridDto?.gridOptions.extraFilterDto) {
|
|
|
|
|
|
setExtraFilters(
|
|
|
|
|
|
gridDto.gridOptions.extraFilterDto.map((f) => ({
|
|
|
|
|
|
fieldName: f.fieldName,
|
|
|
|
|
|
operator: f.operator,
|
|
|
|
|
|
controlType: f.controlType,
|
|
|
|
|
|
value: f.defaultValue ?? '',
|
|
|
|
|
|
})),
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
2025-05-06 06:45:49 +00:00
|
|
|
|
}, [gridDto])
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2025-09-18 21:12:08 +00:00
|
|
|
|
if (!gridDto) return
|
2025-05-06 06:45:49 +00:00
|
|
|
|
|
|
|
|
|
|
const cols = getBandedColumns()
|
|
|
|
|
|
setColumnData(cols)
|
|
|
|
|
|
|
2025-09-19 13:30:19 +00:00
|
|
|
|
const dataSource = createSelectDataSource(gridDto.gridOptions, listFormCode, searchParams, cols)
|
|
|
|
|
|
setGridDataSource(dataSource)
|
|
|
|
|
|
}, [gridDto, searchParams])
|
2025-09-17 14:13:48 +00:00
|
|
|
|
|
2025-09-19 13:30:19 +00:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
const activeFilters = extraFilters.filter((f) => f.value)
|
|
|
|
|
|
|
|
|
|
|
|
let filter: any = null
|
|
|
|
|
|
|
|
|
|
|
|
if (activeFilters.length === 1) {
|
|
|
|
|
|
filter = [activeFilters[0].fieldName, activeFilters[0].operator, activeFilters[0].value]
|
|
|
|
|
|
} else if (activeFilters.length > 1) {
|
|
|
|
|
|
filter = activeFilters.reduce((acc, f, idx) => {
|
|
|
|
|
|
if (idx === 0) return [f.fieldName, f.operator, f.value]
|
|
|
|
|
|
return [acc, 'and', [f.fieldName, f.operator, f.value]]
|
|
|
|
|
|
}, null as any)
|
2025-09-18 21:12:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-19 13:30:19 +00:00
|
|
|
|
if (filter) {
|
|
|
|
|
|
// hem defaultFilter hem extraFilter birleştir
|
|
|
|
|
|
if (defaultSearchParamsFilter.current) {
|
|
|
|
|
|
const base = JSON.parse(defaultSearchParamsFilter.current)
|
|
|
|
|
|
filter = [base, 'and', filter]
|
|
|
|
|
|
}
|
|
|
|
|
|
searchParams?.set('filter', JSON.stringify(filter))
|
2025-09-18 21:12:08 +00:00
|
|
|
|
} else {
|
2025-09-19 13:30:19 +00:00
|
|
|
|
// sadece default filter kalsın
|
|
|
|
|
|
if (defaultSearchParamsFilter.current) {
|
|
|
|
|
|
searchParams?.set('filter', defaultSearchParamsFilter.current)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
searchParams?.delete('filter')
|
|
|
|
|
|
}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-19 13:30:19 +00:00
|
|
|
|
gridRef.current?.instance.refresh()
|
|
|
|
|
|
}, [extraFilters])
|
2025-05-06 06:45:49 +00:00
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
refListFormCode.current = listFormCode
|
|
|
|
|
|
if (!gridRef?.current) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gridRef.current.instance.option('remoteOperations', { groupPaging: true })
|
|
|
|
|
|
gridRef.current.instance.option('columns', columnData)
|
|
|
|
|
|
gridRef.current.instance.option('dataSource', gridDataSource)
|
|
|
|
|
|
|
|
|
|
|
|
const stateStoring: IStateStoringProps = {
|
|
|
|
|
|
enabled: gridDto?.gridOptions.stateStoringDto?.enabled,
|
|
|
|
|
|
type: gridDto?.gridOptions.stateStoringDto?.type,
|
|
|
|
|
|
savingTimeout: gridDto?.gridOptions.stateStoringDto?.savingTimeout,
|
|
|
|
|
|
storageKey: gridDto?.gridOptions.stateStoringDto?.storageKey,
|
|
|
|
|
|
}
|
|
|
|
|
|
if (
|
|
|
|
|
|
gridDto?.gridOptions.stateStoringDto?.enabled &&
|
|
|
|
|
|
gridDto?.gridOptions.stateStoringDto?.type === 'custom'
|
|
|
|
|
|
) {
|
|
|
|
|
|
stateStoring.customSave = customSaveState
|
|
|
|
|
|
stateStoring.customLoad = customLoadState
|
|
|
|
|
|
}
|
|
|
|
|
|
gridRef.current.instance.option('stateStoring', stateStoring)
|
|
|
|
|
|
}, [columnData])
|
|
|
|
|
|
|
2025-08-18 14:55:51 +00:00
|
|
|
|
const onExporting = async (e: DataGridTypes.ExportingEvent) => {
|
|
|
|
|
|
// DevExtreme’in varsayılan export davranışını iptal ediyoruz; kendi akışımızı çalıştıracağız
|
|
|
|
|
|
e.cancel = true
|
|
|
|
|
|
|
|
|
|
|
|
const grid = gridRef?.current?.instance
|
|
|
|
|
|
if (!grid) return
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (e.format === 'xlsx' || e.format === 'csv') {
|
|
|
|
|
|
// exceljs + file-saver + devextreme excel exporter => ihtiyaç anında yükle
|
|
|
|
|
|
const [{ Workbook }, { saveAs }, { exportDataGrid: exportDataExcel }] = await Promise.all([
|
|
|
|
|
|
import('exceljs'),
|
|
|
|
|
|
import('file-saver'),
|
|
|
|
|
|
import('devextreme/excel_exporter'),
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
const workbook = new Workbook()
|
|
|
|
|
|
const worksheet = workbook.addWorksheet(`${listFormCode}_sheet`)
|
|
|
|
|
|
|
|
|
|
|
|
await exportDataExcel({
|
|
|
|
|
|
component: grid,
|
|
|
|
|
|
worksheet,
|
|
|
|
|
|
autoFilterEnabled: true,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if (e.format === 'xlsx') {
|
|
|
|
|
|
const buffer = await workbook.xlsx.writeBuffer()
|
2025-07-28 12:48:30 +00:00
|
|
|
|
saveAs(
|
|
|
|
|
|
new Blob([buffer], { type: 'application/octet-stream' }),
|
|
|
|
|
|
`${listFormCode}_export.xlsx`,
|
|
|
|
|
|
)
|
2025-08-18 14:55:51 +00:00
|
|
|
|
} else {
|
|
|
|
|
|
const buffer = await workbook.csv.writeBuffer()
|
2025-07-28 12:48:30 +00:00
|
|
|
|
saveAs(
|
|
|
|
|
|
new Blob([buffer], { type: 'application/octet-stream' }),
|
|
|
|
|
|
`${listFormCode}_export.csv`,
|
|
|
|
|
|
)
|
2025-08-18 14:55:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
} else if (e.format === 'pdf') {
|
|
|
|
|
|
// jspdf + devextreme pdf exporter => ihtiyaç anında yükle
|
|
|
|
|
|
const [jspdfMod, { exportDataGrid: exportDataPdf }] = await Promise.all([
|
|
|
|
|
|
import('jspdf'),
|
|
|
|
|
|
import('devextreme/pdf_exporter'),
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// jsPDF bazı paketlemelerde default, bazılarında named export olarak gelir
|
|
|
|
|
|
const JsPDFCtor = (jspdfMod as any).default ?? (jspdfMod as any).jsPDF
|
|
|
|
|
|
const doc = new JsPDFCtor({})
|
|
|
|
|
|
|
|
|
|
|
|
await exportDataPdf({
|
|
|
|
|
|
jsPDFDocument: doc,
|
|
|
|
|
|
component: grid,
|
|
|
|
|
|
indent: 5,
|
2025-05-06 06:45:49 +00:00
|
|
|
|
})
|
2025-08-18 14:55:51 +00:00
|
|
|
|
|
|
|
|
|
|
doc.save(`${listFormCode}_export.pdf`)
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
console.error('Export error:', err)
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="danger" duration={2500}>
|
|
|
|
|
|
{translate('::App.Common.ExportError') ?? 'Dışa aktarma sırasında hata oluştu.'}
|
|
|
|
|
|
</Notification>,
|
2025-09-01 14:07:03 +00:00
|
|
|
|
{ placement: 'top-end' },
|
2025-08-18 14:55:51 +00:00
|
|
|
|
)
|
2025-05-06 06:45:49 +00:00
|
|
|
|
}
|
2025-07-28 12:48:30 +00:00
|
|
|
|
}
|
2025-05-06 06:45:49 +00:00
|
|
|
|
|
|
|
|
|
|
return (
|
2025-09-12 11:26:35 +00:00
|
|
|
|
<>
|
|
|
|
|
|
<WidgetGroup widgetGroups={widgetGroups} />
|
|
|
|
|
|
|
|
|
|
|
|
<Container className={DX_CLASSNAMES}>
|
|
|
|
|
|
{!isSubForm && (
|
|
|
|
|
|
<Helmet
|
2025-09-13 11:46:34 +00:00
|
|
|
|
titleTemplate="%s | Sözsoft Kurs Platform"
|
2025-09-12 11:26:35 +00:00
|
|
|
|
title={translate('::' + gridDto?.gridOptions.title)}
|
2025-09-13 11:46:34 +00:00
|
|
|
|
defaultTitle="Sözsoft Kurs Platform"
|
2025-09-12 11:26:35 +00:00
|
|
|
|
></Helmet>
|
|
|
|
|
|
)}
|
|
|
|
|
|
{gridDto && columnData && (
|
2025-09-17 14:13:48 +00:00
|
|
|
|
<>
|
|
|
|
|
|
<div className="p-1">
|
|
|
|
|
|
<DataGrid
|
|
|
|
|
|
ref={gridRef as any}
|
|
|
|
|
|
id={'Grid-' + listFormCode}
|
|
|
|
|
|
//dataSource={gridDataSource}
|
|
|
|
|
|
//remoteOperations={{ groupPaging: true }}
|
|
|
|
|
|
//remoteOperations={false}
|
|
|
|
|
|
height={gridDto.gridOptions.height || '100%'}
|
|
|
|
|
|
width={gridDto.gridOptions.width || '100%'}
|
|
|
|
|
|
allowColumnResizing={gridDto.gridOptions.columnOptionDto?.allowColumnResizing}
|
|
|
|
|
|
allowColumnReordering={gridDto.gridOptions.columnOptionDto?.allowColumnReordering}
|
|
|
|
|
|
showBorders={gridDto.gridOptions.columnOptionDto?.showBorders}
|
|
|
|
|
|
showRowLines={gridDto.gridOptions.columnOptionDto?.showRowLines}
|
|
|
|
|
|
showColumnLines={gridDto.gridOptions.columnOptionDto?.showColumnLines}
|
|
|
|
|
|
columnResizingMode={gridDto.gridOptions.columnOptionDto?.columnResizingMode}
|
|
|
|
|
|
columnAutoWidth={gridDto.gridOptions.columnOptionDto?.columnAutoWidth}
|
|
|
|
|
|
rtlEnabled={gridDto.gridOptions.columnOptionDto?.rtlEnabled}
|
|
|
|
|
|
rowAlternationEnabled={gridDto.gridOptions.columnOptionDto?.rowAlternationEnabled}
|
|
|
|
|
|
hoverStateEnabled={gridDto.gridOptions.columnOptionDto?.hoverStateEnabled}
|
|
|
|
|
|
columnHidingEnabled={gridDto.gridOptions.columnOptionDto?.columnHidingEnabled}
|
|
|
|
|
|
focusedRowEnabled={gridDto.gridOptions.columnOptionDto?.focusedRowEnabled}
|
|
|
|
|
|
showColumnHeaders={gridDto.gridOptions.columnOptionDto?.showColumnHeaders}
|
|
|
|
|
|
filterSyncEnabled={true}
|
2025-09-19 13:30:19 +00:00
|
|
|
|
onContentReady={(e) => {
|
|
|
|
|
|
const ds = e.component.getDataSource()
|
|
|
|
|
|
if (!ds) return
|
|
|
|
|
|
|
|
|
|
|
|
const store = ds.store() as any
|
|
|
|
|
|
if (store._widgets) {
|
|
|
|
|
|
setWidgetGroups(store._widgets)
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
onSelectionChanged={onSelectionChanged}
|
|
|
|
|
|
onInitNewRow={onInitNewRow}
|
|
|
|
|
|
onCellPrepared={onCellPrepared}
|
|
|
|
|
|
onRowInserting={onRowInserting}
|
|
|
|
|
|
onRowUpdating={onRowUpdating}
|
|
|
|
|
|
onEditingStart={onEditingStart}
|
|
|
|
|
|
onDataErrorOccurred={onDataErrorOccurred}
|
|
|
|
|
|
onExporting={onExporting}
|
|
|
|
|
|
onEditCanceled={() => {
|
|
|
|
|
|
setMode('view')
|
|
|
|
|
|
}}
|
|
|
|
|
|
onSaved={() => {
|
|
|
|
|
|
setMode('view')
|
|
|
|
|
|
}}
|
|
|
|
|
|
onRowInserted={() => {
|
|
|
|
|
|
props.refreshData?.()
|
2025-09-12 11:26:35 +00:00
|
|
|
|
}}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
onRowUpdated={() => {
|
|
|
|
|
|
props.refreshData?.()
|
|
|
|
|
|
}}
|
|
|
|
|
|
onRowRemoved={() => {
|
|
|
|
|
|
props.refreshData?.()
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Export
|
|
|
|
|
|
enabled={true}
|
|
|
|
|
|
allowExportSelectedData={false}
|
|
|
|
|
|
formats={['pdf', 'xlsx', 'csv']}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<Editing
|
|
|
|
|
|
refreshMode={gridDto.gridOptions.editingOptionDto?.refreshMode}
|
|
|
|
|
|
mode={smaller.md ? 'form' : gridDto.gridOptions.editingOptionDto?.mode}
|
|
|
|
|
|
allowDeleting={gridDto.gridOptions.editingOptionDto?.allowDeleting}
|
|
|
|
|
|
allowUpdating={gridDto.gridOptions.editingOptionDto?.allowUpdating}
|
|
|
|
|
|
allowAdding={gridDto.gridOptions.editingOptionDto?.allowAdding}
|
|
|
|
|
|
useIcons={gridDto.gridOptions.editingOptionDto?.useIcons}
|
|
|
|
|
|
confirmDelete={gridDto.gridOptions.editingOptionDto?.confirmDelete}
|
|
|
|
|
|
newRowPosition={gridDto.gridOptions.editingOptionDto?.newRowPosition}
|
|
|
|
|
|
selectTextOnEditStart={
|
|
|
|
|
|
gridDto.gridOptions.editingOptionDto?.selectTextOnEditStart
|
|
|
|
|
|
}
|
|
|
|
|
|
startEditAction={gridDto.gridOptions.editingOptionDto?.startEditAction}
|
|
|
|
|
|
popup={{
|
|
|
|
|
|
title: gridDto.gridOptions.editingOptionDto?.popup?.title,
|
|
|
|
|
|
showTitle: gridDto.gridOptions.editingOptionDto?.popup?.showTitle,
|
|
|
|
|
|
hideOnOutsideClick:
|
|
|
|
|
|
gridDto.gridOptions.editingOptionDto?.popup?.hideOnOutsideClick,
|
|
|
|
|
|
width: gridDto.gridOptions.editingOptionDto?.popup?.width,
|
|
|
|
|
|
height: gridDto.gridOptions.editingOptionDto?.popup?.height,
|
|
|
|
|
|
fullScreen: gridDto.gridOptions.editingOptionDto?.popup?.fullScreen,
|
|
|
|
|
|
}}
|
|
|
|
|
|
form={{
|
|
|
|
|
|
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 = {}
|
|
|
|
|
|
try {
|
|
|
|
|
|
editorOptions = i.editorOptions && JSON.parse(i.editorOptions)
|
|
|
|
|
|
|
|
|
|
|
|
// Eğer default value varsa, bu editörü readonly yapıyoruz
|
2025-09-19 13:30:19 +00:00
|
|
|
|
const rawFilter = searchParams?.get('filter')
|
|
|
|
|
|
if (rawFilter) {
|
|
|
|
|
|
const parsed = JSON.parse(rawFilter) as [
|
|
|
|
|
|
string,
|
|
|
|
|
|
string,
|
|
|
|
|
|
any,
|
|
|
|
|
|
]
|
|
|
|
|
|
const [field, op, val] = parsed
|
|
|
|
|
|
if (field === i.dataField) {
|
|
|
|
|
|
editorOptions = {
|
|
|
|
|
|
...editorOptions,
|
|
|
|
|
|
readOnly: true,
|
|
|
|
|
|
}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch {}
|
|
|
|
|
|
const fieldName = i.dataField.split(':')[0]
|
|
|
|
|
|
const listFormField = gridDto.columnFormats.find(
|
|
|
|
|
|
(x: any) => x.fieldName === fieldName,
|
|
|
|
|
|
)
|
|
|
|
|
|
if (listFormField?.sourceDbType === DbTypeEnum.Date) {
|
2025-09-12 11:26:35 +00:00
|
|
|
|
editorOptions = {
|
2025-09-17 14:13:48 +00:00
|
|
|
|
...{
|
|
|
|
|
|
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',
|
|
|
|
|
|
},
|
2025-09-12 11:26:35 +00:00
|
|
|
|
...editorOptions,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
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,
|
2025-09-12 11:26:35 +00:00
|
|
|
|
}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
if (i.dataField.indexOf(':') >= 0) {
|
|
|
|
|
|
item.label = { text: captionize(i.dataField.split(':')[1]) }
|
2025-05-06 06:45:49 +00:00
|
|
|
|
}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
if (
|
|
|
|
|
|
(mode == 'edit' && !item.canUpdate) ||
|
|
|
|
|
|
(mode == 'new' && !item.canCreate)
|
|
|
|
|
|
) {
|
|
|
|
|
|
item.editorOptions = {
|
|
|
|
|
|
...item.editorOptions,
|
|
|
|
|
|
readOnly: true,
|
|
|
|
|
|
}
|
2025-09-12 11:26:35 +00:00
|
|
|
|
}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
} as GroupItem
|
|
|
|
|
|
})
|
|
|
|
|
|
: undefined,
|
|
|
|
|
|
}}
|
|
|
|
|
|
></Editing>
|
|
|
|
|
|
<Template name={'cellEditTagBox'} render={TagBoxEditorComponent} />
|
|
|
|
|
|
<Template name={'cellEditGridBox'} render={GridBoxEditorComponent} />
|
|
|
|
|
|
<Template name="extraFilters">
|
|
|
|
|
|
<GridExtraFilterToolbar
|
|
|
|
|
|
filters={gridDto?.gridOptions.extraFilterDto ?? []}
|
|
|
|
|
|
extraFilters={extraFilters}
|
|
|
|
|
|
setExtraFilters={setExtraFilters}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Template>
|
|
|
|
|
|
<Toolbar visible={toolbarData.length > 0 || filterToolbarData.length > 0}>
|
|
|
|
|
|
{toolbarData.map((item) => (
|
|
|
|
|
|
<Item key={item.name} {...item}></Item>
|
2025-09-12 11:26:35 +00:00
|
|
|
|
))}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
{filterToolbarData.map((item) => (
|
|
|
|
|
|
<Item key={item.name} {...item}></Item>
|
2025-09-12 11:26:35 +00:00
|
|
|
|
))}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
{/* burada özel filtre alanını Template ile bağla */}
|
|
|
|
|
|
{gridDto?.gridOptions.extraFilterDto?.length ? (
|
2025-09-19 13:30:19 +00:00
|
|
|
|
<Item location="before" template="extraFilters" cssClass="no-default" />
|
2025-09-17 14:13:48 +00:00
|
|
|
|
) : null}
|
|
|
|
|
|
</Toolbar>
|
|
|
|
|
|
<Sorting mode={gridDto.gridOptions?.sortMode}></Sorting>
|
|
|
|
|
|
<FilterRow
|
|
|
|
|
|
visible={gridDto.gridOptions.filterRowDto?.visible}
|
|
|
|
|
|
applyFilter={gridDto.gridOptions.filterRowDto?.applyFilter}
|
|
|
|
|
|
></FilterRow>
|
|
|
|
|
|
<FilterPanel visible={gridDto.gridOptions.filterPanelDto.visible}></FilterPanel>
|
|
|
|
|
|
<HeaderFilter visible={gridDto.gridOptions.headerFilterDto.visible}></HeaderFilter>
|
|
|
|
|
|
<SearchPanel
|
|
|
|
|
|
visible={gridDto.gridOptions.searchPanelDto.visible}
|
|
|
|
|
|
width={gridDto.gridOptions.searchPanelDto.width}
|
|
|
|
|
|
></SearchPanel>
|
|
|
|
|
|
<GroupPanel visible={gridDto.gridOptions.groupPanelDto?.visible}></GroupPanel>
|
|
|
|
|
|
<Grouping
|
|
|
|
|
|
autoExpandAll={gridDto.gridOptions.groupPanelDto?.autoExpandAll}
|
|
|
|
|
|
></Grouping>
|
|
|
|
|
|
<Selection
|
|
|
|
|
|
mode={gridDto.gridOptions.selectionDto?.mode}
|
|
|
|
|
|
allowSelectAll={gridDto.gridOptions.selectionDto?.allowSelectAll}
|
|
|
|
|
|
selectAllMode={gridDto.gridOptions.selectionDto?.selectAllMode}
|
|
|
|
|
|
showCheckBoxesMode={gridDto.gridOptions.selectionDto?.showCheckBoxesMode}
|
|
|
|
|
|
></Selection>
|
|
|
|
|
|
{/* <Paging pageSize={gridDto.gridOptions.pageSize ?? 0}></Paging> */}
|
|
|
|
|
|
<Pager
|
|
|
|
|
|
visible={gridDto.gridOptions.pagerOptionDto?.visible}
|
|
|
|
|
|
allowedPageSizes={gridDto.gridOptions.pagerOptionDto?.allowedPageSizes
|
|
|
|
|
|
?.split(',')
|
|
|
|
|
|
.map((a: any) => +a)}
|
|
|
|
|
|
showPageSizeSelector={gridDto.gridOptions.pagerOptionDto?.showPageSizeSelector}
|
|
|
|
|
|
showInfo={gridDto.gridOptions.pagerOptionDto?.showInfo}
|
|
|
|
|
|
showNavigationButtons={gridDto.gridOptions.pagerOptionDto?.showNavigationButtons}
|
|
|
|
|
|
infoText={gridDto.gridOptions.pagerOptionDto?.infoText}
|
|
|
|
|
|
displayMode={gridDto.gridOptions.pagerOptionDto?.displayMode}
|
|
|
|
|
|
></Pager>
|
|
|
|
|
|
<ColumnChooser
|
|
|
|
|
|
enabled={gridDto.gridOptions.columnOptionDto?.columnChooserEnabled}
|
|
|
|
|
|
mode={gridDto.gridOptions.columnOptionDto?.columnChooserMode}
|
|
|
|
|
|
></ColumnChooser>
|
|
|
|
|
|
<ColumnFixing
|
|
|
|
|
|
enabled={gridDto.gridOptions.columnOptionDto?.columnFixingEnabled}
|
|
|
|
|
|
></ColumnFixing>
|
|
|
|
|
|
<Scrolling mode={gridDto.gridOptions.pagerOptionDto?.scrollingMode}></Scrolling>
|
|
|
|
|
|
<LoadPanel
|
|
|
|
|
|
enabled={gridDto.gridOptions.pagerOptionDto?.loadPanelEnabled}
|
|
|
|
|
|
text={gridDto.gridOptions.pagerOptionDto?.loadPanelText}
|
|
|
|
|
|
></LoadPanel>
|
|
|
|
|
|
<Summary>
|
|
|
|
|
|
{gridDto.columnFormats
|
|
|
|
|
|
.filter((x: any) => !!x.columnTotalSummaryDto?.summaryType)
|
|
|
|
|
|
.map((x: any) => (
|
|
|
|
|
|
<TotalItem
|
|
|
|
|
|
key={`Total_${x.fieldName}`}
|
|
|
|
|
|
column={x.fieldName}
|
|
|
|
|
|
summaryType={x.columnTotalSummaryDto.summaryType as any}
|
|
|
|
|
|
showInColumn={x.columnTotalSummaryDto.showInColumn}
|
|
|
|
|
|
valueFormat={x.columnTotalSummaryDto.valueFormat}
|
|
|
|
|
|
displayFormat={x.columnTotalSummaryDto.displayFormat}
|
|
|
|
|
|
/>
|
|
|
|
|
|
))}
|
|
|
|
|
|
{gridDto.columnFormats
|
|
|
|
|
|
.filter((x: any) => !!x.columnGroupSummaryDto?.summaryType)
|
|
|
|
|
|
.map((x: any) => (
|
|
|
|
|
|
<GroupItemDx
|
|
|
|
|
|
key={`Group_${x.fieldName}`}
|
|
|
|
|
|
column={x.fieldName}
|
|
|
|
|
|
summaryType={x.columnGroupSummaryDto.summaryType as any}
|
|
|
|
|
|
showInColumn={x.columnGroupSummaryDto.showInColumn}
|
|
|
|
|
|
valueFormat={x.columnGroupSummaryDto.valueFormat}
|
|
|
|
|
|
displayFormat={x.columnGroupSummaryDto.displayFormat}
|
|
|
|
|
|
/>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</Summary>
|
|
|
|
|
|
</DataGrid>
|
|
|
|
|
|
|
|
|
|
|
|
{gridDto?.gridOptions?.subFormsDto?.length > 0 && (
|
|
|
|
|
|
<>
|
2025-09-19 13:30:19 +00:00
|
|
|
|
<hr className="my-2" />
|
2025-09-17 14:13:48 +00:00
|
|
|
|
<SubForms gridDto={gridDto!} formData={formData} level={level ?? 0} />
|
|
|
|
|
|
</>
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
<Dialog
|
|
|
|
|
|
width={smaller.md ? '100%' : 1000}
|
|
|
|
|
|
isOpen={filterData.isImportModalOpen || false}
|
|
|
|
|
|
onClose={() => filterData.setIsImportModalOpen(false)}
|
|
|
|
|
|
onRequestClose={() => filterData.setIsImportModalOpen(false)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<ImportDashboard gridDto={gridDto} />
|
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</>
|
2025-09-12 11:26:35 +00:00
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
<Dialog
|
|
|
|
|
|
isOpen={toolbarModalData?.open || false}
|
|
|
|
|
|
onClose={() => setToolbarModalData(undefined)}
|
|
|
|
|
|
onRequestClose={() => setToolbarModalData(undefined)}
|
|
|
|
|
|
>
|
|
|
|
|
|
{toolbarModalData?.content}
|
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
<GridFilterDialogs gridRef={gridRef} listFormCode={listFormCode} {...filterData} />
|
|
|
|
|
|
</Container>
|
|
|
|
|
|
</>
|
2025-05-06 06:45:49 +00:00
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default Grid
|