erp-platform/ui/src/views/list/Pivot.tsx

356 lines
13 KiB
TypeScript
Raw Normal View History

2025-05-06 06:45:49 +00:00
/* eslint-disable @typescript-eslint/no-explicit-any */
import Container from '@/components/shared/Container'
import { DX_CLASSNAMES } from '@/constants/app.constant'
import { GridDto, ListFormCustomizationTypeEnum } from '@/proxy/form/models'
import { getList } from '@/services/form.service'
2025-05-06 06:45:49 +00:00
import {
getListFormCustomization,
postListFormCustomization,
} 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 Chart, { CommonSeriesSettings, Size, Tooltip } from 'devextreme-react/chart'
import PivotGrid, {
FieldChooser,
FieldPanel,
HeaderFilter,
IStateStoringProps,
PivotGridTypes,
Scrolling,
Search,
} from 'devextreme-react/pivot-grid'
import CustomStore from 'devextreme/data/custom_store'
import PivotGridDataSource, { Field } from 'devextreme/ui/pivot_grid/data_source'
import { useCallback, useEffect, useRef, useState } from 'react'
import { Helmet } from 'react-helmet'
import { GridColumnData } from './GridColumnData'
import {
addCss,
addJs,
controlStyleCondition,
pivotFieldConvertDataType,
setGridPanelColor,
} from './Utils'
import { useFilters } from './useFilters'
interface GridProps {
listFormCode: string
searchParams?: URLSearchParams
isSubForm?: boolean
level?: number
refreshData?: () => Promise<void>
2025-09-22 14:08:42 +00:00
gridDto?: GridDto
2025-05-06 06:45:49 +00:00
}
const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' // kullanici tanimli gridState ile islem gormus gridin paneline ait renk
const Pivot = (props: GridProps) => {
2025-09-22 14:08:42 +00:00
const { listFormCode, searchParams, isSubForm, level, gridDto } = props
2025-05-06 06:45:49 +00:00
const { translate } = useLocalization()
const gridRef = useRef<PivotGrid>()
const chartRef = useRef<Chart>(null)
const refListFormCode = useRef('')
const [gridDataSource, setGridDataSource] = useState<CustomStore<any, any>>()
const [columnData, setColumnData] = useState<GridColumnData[]>()
const { filterToolbarData, ...filterData } = useFilters({
gridDto,
gridRef,
listFormCode,
})
const { createSelectDataSource } = useListFormCustomDataSource({ pivotRef: gridRef })
const { getBandedColumns } = useListFormColumns({
gridDto,
listFormCode,
isSubForm,
})
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)
}
}
}
}
}
}
}
const customSaveState = useCallback(
(state: any) =>
postListFormCustomization({
listFormCode: listFormCode,
customizationType: ListFormCustomizationTypeEnum.GridState,
filterName: `pivot-${gridRef.current?.instance.option('stateStoring')?.storageKey ?? ''}`,
customizationData: JSON.stringify(state),
}).then(() => {
setGridPanelColor(statedGridPanelColor)
}),
[listFormCode],
)
const customLoadState = useCallback(
() =>
getListFormCustomization(
listFormCode,
ListFormCustomizationTypeEnum.GridState,
`pivot-${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('remoteOperations', false)
gridRef.current.instance.option('dataSource', undefined)
gridRef.current.instance.option('stateStoring', undefined)
}
}, [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)
}
}
}, [gridDto])
useEffect(() => {
if (!gridDto) {
return
}
// Set columns
const cols = getBandedColumns()
setColumnData(cols?.filter((a) => a.colData?.pivotSettingsDto.isPivot))
// Set data source
const dataSource: CustomStore<any, any> = createSelectDataSource(
gridDto.gridOptions,
listFormCode,
searchParams,
cols,
)
setGridDataSource(dataSource)
}, [gridDto, searchParams])
useEffect(() => {
refListFormCode.current = listFormCode
if (!gridRef?.current) {
return
}
const fields: any = columnData?.map((b) => {
return {
dataField: b.dataField,
caption: b.caption,
dataType: pivotFieldConvertDataType(b.dataType),
area: b.colData?.pivotSettingsDto.area,
format: b.colData?.pivotSettingsDto.format,
summaryType: b.colData?.pivotSettingsDto.summaryType,
groupInterval: b.colData?.pivotSettingsDto.groupInterval,
sortOrder: b.colData?.pivotSettingsDto.sortOrder,
expanded: b.colData?.pivotSettingsDto.expanded,
wordWrapEnabled: b.colData?.pivotSettingsDto.wordWrapEnabled,
visible: true,
width: b.width,
} as Field
})
PivotGridDataSource
const dataSource: PivotGridTypes.Properties['dataSource'] = {
remoteOperations: true,
store: gridDataSource,
fields,
}
gridRef.current.instance.option('dataSource', dataSource)
gridRef.current.instance.option('state', null)
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)
//chart Integration
if (gridRef && chartRef) {
gridRef?.current?.instance.bindChart(chartRef?.current?.instance, {
dataFieldsDisplayMode: 'splitPanes',
alternateDataFields: false,
})
}
}, [columnData])
return (
<Container className={DX_CLASSNAMES}>
{!isSubForm && (
<Helmet
2025-09-13 11:46:34 +00:00
titleTemplate="%s | Sözsoft Kurs Platform"
2025-05-06 06:45:49 +00:00
title={translate('::' + gridDto?.gridOptions.title)}
2025-09-13 11:46:34 +00:00
defaultTitle="Sözsoft Kurs Platform"
2025-05-06 06:45:49 +00:00
></Helmet>
)}
{gridDto && columnData && (
<>
{gridDto.gridOptions.columnOptionDto.showChart && (
<Chart ref={chartRef as any}>
<Size height={gridDto.gridOptions.columnOptionDto.chartHeight} />
<Tooltip enabled={true}></Tooltip>
<CommonSeriesSettings
type={gridDto.gridOptions.columnOptionDto.chartCommonSeriesType}
/>
</Chart>
)}
<PivotGrid
ref={gridRef as any}
id={'Pivot-' + listFormCode}
allowFiltering={gridDto.gridOptions.filterRowDto.visible}
allowSorting={gridDto.gridOptions.sortMode !== 'none'}
allowSortingBySummary={gridDto.gridOptions.sortMode !== 'none'}
height={gridDto.gridOptions.height || '100%'}
width={gridDto.gridOptions.width || '100%'}
showBorders={gridDto.gridOptions.columnOptionDto?.showBorders}
rtlEnabled={gridDto.gridOptions.columnOptionDto?.rtlEnabled}
hoverStateEnabled={gridDto.gridOptions.columnOptionDto?.hoverStateEnabled}
onCellPrepared={onCellPrepared}
>
<HeaderFilter
allowSelectAll={gridDto.gridOptions.selectionDto.allowSelectAll}
width={gridDto.gridOptions.headerFilterDto.width}
height={gridDto.gridOptions.headerFilterDto.height}
>
<Search
enabled={gridDto.gridOptions.headerFilterDto.allowSearch}
timeout={gridDto.gridOptions.headerFilterDto.searchTimeout}
></Search>
</HeaderFilter>
<FieldPanel
allowFieldDragging={gridDto.gridOptions.columnOptionDto.allowFieldDragging}
visible={gridDto.gridOptions.columnOptionDto.showFieldPanel}
showDataFields={gridDto.gridOptions.columnOptionDto.showDataFields}
showColumnFields={gridDto.gridOptions.columnOptionDto.showColumnFields}
showRowFields={gridDto.gridOptions.columnOptionDto.showRowFields}
showFilterFields={gridDto.gridOptions.columnOptionDto.showFilterFields}
/>
<FieldChooser
enabled={gridDto.gridOptions.columnOptionDto.columnChooserEnabled}
height={500}
/>
<Scrolling mode={gridDto.gridOptions.pagerOptionDto.scrollingMode} />
</PivotGrid>
</>
)}
</Container>
)
}
export default Pivot
/*
<Toolbar visible={toolbarData.length > 0 || filterToolbarData.length > 0}>
{toolbarData.map((item) => (
<Item key={item.name} {...item}></Item>
))}
{filterToolbarData.map((item) => (
<Item key={item.name} {...item}></Item>
))}
</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>
<Pager
visible={gridDto.gridOptions.pagerOptionDto?.visible}
allowedPageSizes={gridDto.gridOptions.pagerOptionDto?.allowedPageSizes
?.split(',')
.map((a) => +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>
*/